Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions protocols/v2/noise-sv2/src/initiator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub struct Initiator {
e: Keypair,
// upstream pub key
#[allow(unused)]
pk: XOnlyPublicKey,
responder_authority_pk: Option<XOnlyPublicKey>,
c1: Option<GenericCipher>,
c2: Option<GenericCipher>,
}
Expand Down Expand Up @@ -96,18 +96,22 @@ impl Initiator {
pub fn from_raw_k(key: [u8; 32]) -> Result<Box<Self>, Error> {
let pk =
secp256k1::XOnlyPublicKey::from_slice(&key).map_err(|_| Error::InvalidRawPublicKey)?;
Ok(Self::new(pk))
Ok(Self::new(Some(pk)))
}

pub fn new(pk: XOnlyPublicKey) -> Box<Self> {
pub fn without_pk() -> Result<Box<Self>, Error> {
Ok(Self::new(None))
}

pub fn new(pk: Option<XOnlyPublicKey>) -> Box<Self> {
let mut self_ = Self {
handshake_cipher: None,
k: None,
n: 0,
ck: [0; 32],
h: [0; 32],
e: Self::generate_key(),
pk,
responder_authority_pk: pk,
c1: None,
c2: None,
};
Expand Down Expand Up @@ -226,7 +230,7 @@ impl Initiator {
.0
.serialize();
let rs_pk_xonly = XOnlyPublicKey::from_slice(&rs_pub_key).unwrap();
if signature_message.verify(&rs_pk_xonly) {
if signature_message.verify(&rs_pk_xonly, &self.responder_authority_pk) {
let (temp_k1, temp_k2) = Self::hkdf_2(self.get_ck(), &[]);
let c1 = ChaCha20Poly1305::new(&temp_k1.into());
let c2 = ChaCha20Poly1305::new(&temp_k2.into());
Expand Down
10 changes: 7 additions & 3 deletions protocols/v2/noise-sv2/src/responder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub struct Responder {
e: Keypair,
// Static pub keypair
s: Keypair,
// Authority pub keypair
a: Keypair,
c1: Option<GenericCipher>,
c2: Option<GenericCipher>,
cert_validity: u32,
Expand Down Expand Up @@ -107,15 +109,16 @@ impl Responder {
}
}

pub fn new(s: Keypair, cert_validity: u32) -> Box<Self> {
pub fn new(a: Keypair, cert_validity: u32) -> Box<Self> {
let mut self_ = Self {
handshake_cipher: None,
k: None,
n: 0,
ck: [0; 32],
h: [0; 32],
e: Self::generate_key(),
s,
s: Self::generate_key(),
a,
c1: None,
c2: None,
cert_validity,
Expand Down Expand Up @@ -270,7 +273,7 @@ impl Responder {
ret[7] = not_valid_after[1];
ret[8] = not_valid_after[2];
ret[9] = not_valid_after[3];
SignatureNoiseMessage::sign(&mut ret, &self.s);
SignatureNoiseMessage::sign(&mut ret, &self.s.x_only_public_key().0, &self.a);
ret
}

Expand All @@ -294,6 +297,7 @@ impl Responder {
}
self.e.non_secure_erase();
self.s.non_secure_erase();
self.a.non_secure_erase();
}
}

Expand Down
41 changes: 24 additions & 17 deletions protocols/v2/noise-sv2/src/signature_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,34 @@ impl From<[u8; 74]> for SignatureNoiseMessage {
}

impl SignatureNoiseMessage {
pub fn verify(self, pk: &XOnlyPublicKey) -> bool {
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs() as u32;
if self.valid_from <= now && self.not_valid_after >= now {
let secp = Secp256k1::verification_only();
let (m, s) = self.split();
let m = Message::from_hashed_data::<sha256::Hash>(&m[0..10]);
let s = match Signature::from_slice(&s) {
Ok(s) => s,
_ => return false,
};
secp.verify_schnorr(&s, &m, pk).is_ok()
pub fn verify(self, pk: &XOnlyPublicKey, authority_pk: &Option<XOnlyPublicKey>) -> bool {
if let Some(authority_pk) = authority_pk {
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs() as u32;
if self.valid_from <= now && self.not_valid_after >= now {
let secp = Secp256k1::verification_only();
let (m, s) = self.split();
// m = SHA-256(version || valid_from || not_valid_after || server_static_key)
let m = [&m[0..10], &pk.serialize()].concat();
let m = Message::from_hashed_data::<sha256::Hash>(&m);
let s = match Signature::from_slice(&s) {
Ok(s) => s,
_ => return false,
};
secp.verify_schnorr(&s, &m, authority_pk).is_ok()
} else {
false
}
} else {
false
true
}
}
pub fn sign(msg: &mut [u8; 74], kp: &Keypair) {
pub fn sign(msg: &mut [u8; 74], static_pk: &XOnlyPublicKey, kp: &Keypair) {
let secp = Secp256k1::signing_only();
let m = Message::from_hashed_data::<sha256::Hash>(&msg[0..10]);
let m = [&msg[0..10], &static_pk.serialize()].concat();
let m = Message::from_hashed_data::<sha256::Hash>(&m);
let signature = secp.sign_schnorr(&m, kp);
for (i, b) in signature.as_ref().iter().enumerate() {
msg[10 + i] = *b;
Expand Down
2 changes: 1 addition & 1 deletion protocols/v2/noise-sv2/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{handshake::HandshakeOp, initiator::Initiator, responder::Responder};
fn test_1() {
let key_pair = Responder::generate_key();

let mut initiator = Initiator::new(key_pair.public_key().into());
let mut initiator = Initiator::new(Some(key_pair.public_key().into()));
let mut responder = Responder::new(key_pair, 31449600);
let first_message = initiator.step_0().unwrap();
let (second_message, mut codec_responder) = responder.step_1(first_message).unwrap();
Expand Down
8 changes: 6 additions & 2 deletions roles/jd-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ The configuration file contains the following information:
1. The Upstream connection information which includes the SV2 Pool authority public key
(`upstream_authority_pubkey`) and the SV2 Pool connection address (`upstream_address`) and port
(`upstream_port`).
1. The maximum and minimum SV2 versions (`max_supported_version` and `min_supported_version`)
1. The Job Declarator information which includes the Pool JD connection address (`jd_address`) and the Template Provider connection address to which to connect (`tp_address`).
2. The maximum and minimum SV2 versions (`max_supported_version` and `min_supported_version`)
3. The Job Declarator information which includes the Pool JD connection address (`jd_address`) and the Template Provider connection address to which to connect (`tp_address`).
4. Optionally, you may want to verify that your TP connection is authentic. You may get `tp_authority_public_key` from the logs of your TP, for example:
```
# 2024-02-13T14:59:24Z Template Provider authority key: EguTM8URcZDQVeEBsM4B5vg9weqEUnufA8pm85fG4bZd
```

### Run
1. Copy the `jdc-config-example.toml` into `conf/` directory.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ retry = 10
# tp_address = "127.0.0.1:8442"
# Hosted testnet TP
tp_address = "75.119.150.111:8442"
tp_authority_pub_key = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72"
tp_authority_public_key = "3VANfft6ei6jQq1At7d8nmiZzVhBFS4CiQujdgim1ign"

# Solo Mining config
# List of coinbase outputs used to build the coinbase tx in case of Solo Mining (as last-resort solution of the pools fallback system)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ retry = 10
tp_address = "127.0.0.1:8442"
# Hosted testnet TP
# tp_address = "75.119.150.111:8442"
tp_authority_pub_key = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72"

# Solo Mining config
# List of coinbase outputs used to build the coinbase tx in case of Solo Mining (as last-resort solution of the pools fallback system)
Expand Down
2 changes: 1 addition & 1 deletion roles/jd-client/src/lib/proxy_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub struct ProxyConfig {
pub authority_secret_key: Secp256k1SecretKey,
pub cert_validity_sec: u64,
pub tp_address: String,
pub tp_authority_pub_key: Secp256k1PublicKey,
pub tp_authority_public_key: Option<Secp256k1PublicKey>,
pub retry: u32,
pub upstreams: Vec<Upstream>,
#[serde(deserialize_with = "duration_from_toml")]
Expand Down
9 changes: 6 additions & 3 deletions roles/jd-client/src/lib/template_receiver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl TemplateRx {
task_collector: Arc<Mutex<Vec<AbortHandle>>>,
pool_chaneger_trigger: Arc<Mutex<PoolChangerTrigger>>,
miner_coinbase_outputs: Vec<TxOut>,
authority_public_key: Secp256k1PublicKey,
authority_public_key: Option<Secp256k1PublicKey>,
test_only_do_not_send_solution_to_tp: bool,
) {
let mut encoded_outputs = vec![];
Expand All @@ -62,8 +62,11 @@ impl TemplateRx {
.expect("Invalid coinbase output in config");
let stream = tokio::net::TcpStream::connect(address).await.unwrap();

let pub_key: Secp256k1PublicKey = authority_public_key;
let initiator = Initiator::from_raw_k(pub_key.into_bytes()).unwrap();
let initiator = match authority_public_key {
Copy link
Collaborator

@lorbax lorbax Feb 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you can turn authority_public_key: Option<Secp256k1PublicKey> in a variable authority_public_key_x_only: Option<XOnlyPublicKey> and initialize the initiator with Initiator::new(autority_public_key_x_only). You save some lines of code.
I understand that you didn't write the whole code, but perhaps the methods Initiator::from_raw_k() and Initiator::without_pk() can be eliminated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while I agree this would be a desirable improvement to the code, this would imply refactoring multiple parts of the codebase which don't really have much to do with the context of this PR

so in order to keep PR atomicity, I created this issue so we can implement this improvement in the future:
#760

Some(pub_key) => Initiator::from_raw_k(pub_key.into_bytes()),
None => Initiator::without_pk(),
}
.unwrap();
let (mut receiver, mut sender, _, _) =
Connection::new(stream, HandshakeRole::Initiator(initiator))
.await
Expand Down
4 changes: 2 additions & 2 deletions roles/jd-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ async fn initialize_jd_as_solo_miner(
task_collector,
Arc::new(Mutex::new(PoolChangerTrigger::new(timeout))),
miner_tx_out.clone(),
proxy_config.tp_authority_pub_key,
proxy_config.tp_authority_public_key,
false,
)
.await;
Expand Down Expand Up @@ -384,7 +384,7 @@ async fn initialize_jd(
task_collector,
Arc::new(Mutex::new(PoolChangerTrigger::new(timeout))),
vec![],
proxy_config.tp_authority_pub_key,
proxy_config.tp_authority_public_key,
test_only_do_not_send_solution_to_tp,
)
.await;
Expand Down
4 changes: 4 additions & 0 deletions roles/pool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ The configuration file contains the following information:
1. The SRI Pool information which includes the SRI Pool authority public key
(`authority_pubkey`), the SRI Pool authority secret key (`authority_secret_key`), along with its certificate validity (`cert_validity_sec`). In addition to this, it contains the address which it will use to listen to new connection from downstream roles (`listen_address`) and the list of uncompressed pubkeys for coinbase payout (`coinbase_outputs`).
2. The SRI Pool Job Negatiator information which includes the Template Provider address (`tp_address`) and the address it uses to listen new request from the downstream JDs (`jd_address`).
3. Optionally, you may want to verify that your TP connection is authentic. You may get `tp_authority_public_key` from the logs of your TP, for example:
```
# 2024-02-13T14:59:24Z Template Provider authority key: EguTM8URcZDQVeEBsM4B5vg9weqEUnufA8pm85fG4bZd
```

### Run
1. Copy the `pool-config-example.toml` into `conf/` directory.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ pool_signature = "Stratum v2 SRI Pool"
#tp_address = "127.0.0.1:8442"
# Hosted testnet TP
tp_address = "75.119.150.111:8442"
tp_authority_public_key = "EguTM8URcZDQVeEBsM4B5vg9weqEUnufA8pm85fG4bZd"
2 changes: 0 additions & 2 deletions roles/pool/config-examples/pool-config-local-tp-example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,3 @@ pool_signature = "Stratum v2 SRI Pool"
# Template Provider config
# Local TP (this is pointing to localhost so you must run a TP locally for this configuration to work)
tp_address = "127.0.0.1:8442"
# Hosted testnet TP
# tp_address = "75.119.150.111:8442"
1 change: 1 addition & 0 deletions roles/pool/src/lib/mining_pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ impl TryFrom<&CoinbaseOutput> for CoinbaseOutput_ {
pub struct Configuration {
pub listen_address: String,
pub tp_address: String,
pub tp_authority_public_key: Option<Secp256k1PublicKey>,
pub authority_public_key: Secp256k1PublicKey,
pub authority_secret_key: Secp256k1SecretKey,
pub cert_validity_sec: u64,
Expand Down
10 changes: 7 additions & 3 deletions roles/pool/src/lib/template_receiver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,17 @@ impl TemplateRx {
message_received_signal: Receiver<()>,
status_tx: status::Sender,
coinbase_out_len: u32,
authority_public_key: Secp256k1PublicKey,
expected_tp_authority_public_key: Option<Secp256k1PublicKey>,
) -> PoolResult<()> {
let stream = TcpStream::connect(address).await?;
info!("Connected to template distribution server at {}", address);

let pub_key: Secp256k1PublicKey = authority_public_key;
let initiator = Initiator::from_raw_k(pub_key.into_bytes())?;
let initiator = match expected_tp_authority_public_key {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing of the previous comment

Some(expected_tp_authority_public_key) => {
Initiator::from_raw_k(expected_tp_authority_public_key.into_bytes())
}
None => Initiator::without_pk(),
}?;
let (mut receiver, mut sender, _, _) =
Connection::new(stream, HandshakeRole::Initiator(initiator))
.await
Expand Down
4 changes: 2 additions & 2 deletions roles/pool/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ async fn main() {
return;
}
};
let authority_public_key = config.authority_public_key;
let tp_authority_public_key = config.tp_authority_public_key;
let template_rx_res = TemplateRx::connect(
config.tp_address.parse().unwrap(),
s_new_t,
Expand All @@ -124,7 +124,7 @@ async fn main() {
r_message_recv_signal,
status::Sender::Upstream(status_tx.clone()),
coinbase_output_len,
authority_public_key,
tp_authority_public_key,
)
.await;

Expand Down