mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-26 01:03:40 +00:00
[Remote signer] Fold signer into Lighthouse repository (#1852)
The remote signer relies on the `types` and `crypto/bls` crates from Lighthouse. Moreover, a number of tests of the remote signer consumption of LH leverages this very signer, making any important update a potential dependency nightmare. Co-authored-by: Paul Hauner <paul@paulhauner.com>
This commit is contained in:
123
remote_signer/backend/src/utils.rs
Normal file
123
remote_signer/backend/src/utils.rs
Normal file
@@ -0,0 +1,123 @@
|
||||
use crate::{BackendError, ZeroizeString};
|
||||
use bls::SecretKey;
|
||||
use hex::decode;
|
||||
use std::fmt::{Error, Write};
|
||||
use std::str;
|
||||
|
||||
// hex::encode only allows up to 32 bytes.
|
||||
pub fn bytes96_to_hex_string(data: [u8; 96]) -> Result<String, Error> {
|
||||
static CHARS: &[u8] = b"0123456789abcdef";
|
||||
let mut s = String::with_capacity(96 * 2 + 2);
|
||||
|
||||
s.write_char('0')?;
|
||||
s.write_char('x')?;
|
||||
|
||||
for &byte in data.iter() {
|
||||
s.write_char(CHARS[(byte >> 4) as usize].into())?;
|
||||
s.write_char(CHARS[(byte & 0xf) as usize].into())?;
|
||||
}
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
/// Validates the match as a BLS pair of the public and secret keys given,
|
||||
/// consuming the secret key parameter, and returning a deserialized SecretKey.
|
||||
pub fn validate_bls_pair(
|
||||
public_key: &str,
|
||||
secret_key: ZeroizeString,
|
||||
) -> Result<SecretKey, BackendError> {
|
||||
let secret_key: SecretKey = secret_key.into_bls_sk().map_err(|e| {
|
||||
BackendError::InvalidSecretKey(format!("public_key: {}; {}", public_key, e))
|
||||
})?;
|
||||
|
||||
let pk_param_as_bytes = decode(&public_key)
|
||||
.map_err(|e| BackendError::InvalidPublicKey(format!("{}; {}", public_key, e)))?;
|
||||
|
||||
if &secret_key.public_key().serialize()[..] != pk_param_as_bytes.as_slice() {
|
||||
return Err(BackendError::KeyMismatch(public_key.to_string()));
|
||||
}
|
||||
|
||||
Ok(secret_key)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod functions {
|
||||
use super::*;
|
||||
use helpers::*;
|
||||
|
||||
#[test]
|
||||
fn fn_bytes96_to_hex_string() {
|
||||
assert_eq!(
|
||||
bytes96_to_hex_string(EXPECTED_SIGNATURE_1_BYTES).unwrap(),
|
||||
EXPECTED_SIGNATURE_1
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
bytes96_to_hex_string(EXPECTED_SIGNATURE_2_BYTES).unwrap(),
|
||||
EXPECTED_SIGNATURE_2
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
bytes96_to_hex_string(EXPECTED_SIGNATURE_3_BYTES).unwrap(),
|
||||
EXPECTED_SIGNATURE_3
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fn_validate_bls_pair() {
|
||||
let test_ok_case = |pk: &str, sk: ZeroizeString, sk_bytes: &[u8; 32]| {
|
||||
let serialized_secret_key = validate_bls_pair(pk, sk).unwrap().serialize();
|
||||
assert_eq!(serialized_secret_key.as_bytes().to_vec(), sk_bytes.to_vec());
|
||||
};
|
||||
|
||||
test_ok_case(
|
||||
PUBLIC_KEY_1,
|
||||
ZeroizeString::from(SECRET_KEY_1.to_string()),
|
||||
&SECRET_KEY_1_BYTES,
|
||||
);
|
||||
|
||||
let test_error_case = |pk: &str, sk: ZeroizeString, expected_error: &str| {
|
||||
assert_eq!(
|
||||
validate_bls_pair(pk, sk).err().unwrap().to_string(),
|
||||
expected_error
|
||||
);
|
||||
};
|
||||
|
||||
test_error_case(
|
||||
PUBLIC_KEY_2,
|
||||
ZeroizeString::from("TamperedKey%#$#%#$$&##00£$%$$£%$".to_string()),
|
||||
&format!(
|
||||
"Invalid secret key: public_key: {}; Invalid hex character: T at index 0",
|
||||
PUBLIC_KEY_2
|
||||
),
|
||||
);
|
||||
|
||||
test_error_case(
|
||||
PUBLIC_KEY_2,
|
||||
ZeroizeString::from("deadbeef".to_string()),
|
||||
&format!(
|
||||
"Invalid secret key: public_key: {}; InvalidSecretKeyLength {{ got: 4, expected: 32 }}",
|
||||
PUBLIC_KEY_2
|
||||
),
|
||||
);
|
||||
|
||||
let bad_pk_param = "not_validated_by_the_api_handler!";
|
||||
test_error_case(
|
||||
bad_pk_param,
|
||||
ZeroizeString::from(SECRET_KEY_1.to_string()),
|
||||
&format!("Invalid public key: {}; Odd number of digits", bad_pk_param),
|
||||
);
|
||||
|
||||
test_error_case(
|
||||
PUBLIC_KEY_1,
|
||||
ZeroizeString::from(SECRET_KEY_2.to_string()),
|
||||
&format!("Key mismatch: {}", PUBLIC_KEY_1),
|
||||
);
|
||||
|
||||
test_error_case(
|
||||
PUBLIC_KEY_2,
|
||||
ZeroizeString::from(SECRET_KEY_3.to_string()),
|
||||
&format!("Key mismatch: {}", PUBLIC_KEY_2),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user