mirror of
https://github.com/Blah-IM/blahrs.git
synced 2025-09-13 05:55:22 +00:00
refactor(types): allow SignExt::sign_msg_with
using a fixed nonce
This simplifies tests and avoid the use of deprecated `StepRng`.
This commit is contained in:
parent
583f916cbe
commit
59a8851b32
4 changed files with 27 additions and 26 deletions
|
@ -10,6 +10,7 @@ use rand::{Rng, SeedableRng, rngs::SmallRng};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
const SEED: u64 = 0xDEAD_BEEF_BEEF_DEAD;
|
const SEED: u64 = 0xDEAD_BEEF_BEEF_DEAD;
|
||||||
|
const FIXED_NONCE: u32 = 0x42;
|
||||||
|
|
||||||
const MOCK_PRIV_KEY1: [u8; 32] = *b"this is the testing private key1";
|
const MOCK_PRIV_KEY1: [u8; 32] = *b"this is the testing private key1";
|
||||||
const MOCK_PRIV_KEY2: [u8; 32] = *b"that is the 2nd testing privkey.";
|
const MOCK_PRIV_KEY2: [u8; 32] = *b"that is the 2nd testing privkey.";
|
||||||
|
@ -77,18 +78,14 @@ fn bench_msg_sign_verify(c: &mut Criterion) {
|
||||||
|
|
||||||
let msg = avg_msg();
|
let msg = avg_msg();
|
||||||
c.bench_function("msg-sign", |b| {
|
c.bench_function("msg-sign", |b| {
|
||||||
// FIXME: Provide a deterministic signing method using a given nonce?
|
|
||||||
let fixed_nonce_rng = &mut SmallRng::seed_from_u64(SEED);
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
black_box(msg.clone())
|
black_box(msg.clone())
|
||||||
.sign_msg_with(&id_key, &act_key_priv, timestamp, fixed_nonce_rng)
|
.sign_msg_with(&id_key, &act_key_priv, timestamp, FIXED_NONCE)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let rng = &mut SmallRng::seed_from_u64(SEED);
|
|
||||||
let signed = msg
|
let signed = msg
|
||||||
.sign_msg_with(&id_key, &act_key_priv, timestamp, rng)
|
.sign_msg_with(&id_key, &act_key_priv, timestamp, FIXED_NONCE)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
c.bench_function("msg-verify", |b| {
|
c.bench_function("msg-verify", |b| {
|
||||||
|
|
|
@ -87,20 +87,23 @@ pub struct Signee<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SignExt: Sized {
|
pub trait SignExt: Sized {
|
||||||
|
/// A convenient shortcut method of [`Signed::new`] for method chaining.
|
||||||
fn sign_msg_with(
|
fn sign_msg_with(
|
||||||
self,
|
self,
|
||||||
id_key: &PubKey,
|
id_key: &PubKey,
|
||||||
act_key: &SigningKey,
|
act_key: &SigningKey,
|
||||||
timestamp: u64,
|
timestamp: u64,
|
||||||
rng: &mut (impl RngCore + ?Sized),
|
nonce: u32,
|
||||||
) -> Result<Signed<Self>, SignatureError>;
|
) -> Result<Signed<Self>, SignatureError>;
|
||||||
|
|
||||||
|
/// A convenient shortcut method of [`SignExt::sign_msg`] using the current
|
||||||
|
/// timestamp and a random nonce from [`rand::rng`].
|
||||||
fn sign_msg(
|
fn sign_msg(
|
||||||
self,
|
self,
|
||||||
id_key: &PubKey,
|
id_key: &PubKey,
|
||||||
act_key: &SigningKey,
|
act_key: &SigningKey,
|
||||||
) -> Result<Signed<Self>, SignatureError> {
|
) -> Result<Signed<Self>, SignatureError> {
|
||||||
self.sign_msg_with(id_key, act_key, get_timestamp(), &mut rand::rng())
|
self.sign_msg_with(id_key, act_key, get_timestamp(), rand::rng().next_u32())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,9 +113,9 @@ impl<T: Serialize> SignExt for T {
|
||||||
id_key: &PubKey,
|
id_key: &PubKey,
|
||||||
act_key: &SigningKey,
|
act_key: &SigningKey,
|
||||||
timestamp: u64,
|
timestamp: u64,
|
||||||
rng: &mut (impl RngCore + ?Sized),
|
nonce: u32,
|
||||||
) -> Result<Signed<Self>, SignatureError> {
|
) -> Result<Signed<Self>, SignatureError> {
|
||||||
Signed::new(id_key, act_key, timestamp, rng, self)
|
Signed::new(id_key, act_key, timestamp, nonce, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,15 +141,19 @@ impl<T: Serialize> Signed<T> {
|
||||||
/// Sign the payload with the given `key`.
|
/// Sign the payload with the given `key`.
|
||||||
///
|
///
|
||||||
/// This operation only fail when serialization of `payload` fails.
|
/// This operation only fail when serialization of `payload` fails.
|
||||||
|
///
|
||||||
|
/// This function is pure and portable, if the serialization of `payload` is
|
||||||
|
/// pure and portable. That is, it always returns the bit-identical bytes if
|
||||||
|
/// it returns `Ok` as long as the arguments are bit-identical.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id_key: &PubKey,
|
id_key: &PubKey,
|
||||||
act_key: &SigningKey,
|
act_key: &SigningKey,
|
||||||
timestamp: u64,
|
timestamp: u64,
|
||||||
rng: &mut (impl RngCore + ?Sized),
|
nonce: u32,
|
||||||
payload: T,
|
payload: T,
|
||||||
) -> Result<Self, SignatureError> {
|
) -> Result<Self, SignatureError> {
|
||||||
let signee = Signee {
|
let signee = Signee {
|
||||||
nonce: rng.next_u32(),
|
nonce,
|
||||||
payload,
|
payload,
|
||||||
timestamp,
|
timestamp,
|
||||||
user: UserKey {
|
user: UserKey {
|
||||||
|
|
|
@ -274,9 +274,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn id_desc_verify() {
|
fn id_desc_verify() {
|
||||||
|
// Insecure but deterministic mock values.
|
||||||
const TIMESTAMP: u64 = 42;
|
const TIMESTAMP: u64 = 42;
|
||||||
|
const NONCE: u32 = 42;
|
||||||
|
|
||||||
let rng = &mut rand::rngs::mock::StepRng::new(42, 1);
|
|
||||||
let id_url = "https://example.com".parse::<IdUrl>().unwrap();
|
let id_url = "https://example.com".parse::<IdUrl>().unwrap();
|
||||||
let id_priv = SigningKey::from_bytes(&[42; 32]);
|
let id_priv = SigningKey::from_bytes(&[42; 32]);
|
||||||
let id_key = PubKey::from(id_priv.verifying_key());
|
let id_key = PubKey::from(id_priv.verifying_key());
|
||||||
|
@ -287,7 +288,7 @@ mod tests {
|
||||||
preferred_chat_server_urls: Vec::new(),
|
preferred_chat_server_urls: Vec::new(),
|
||||||
id_urls: vec![id_url],
|
id_urls: vec![id_url],
|
||||||
}
|
}
|
||||||
.sign_msg_with(&id_key, &id_priv, TIMESTAMP, rng)
|
.sign_msg_with(&id_key, &id_priv, TIMESTAMP, NONCE)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -319,7 +320,7 @@ mod tests {
|
||||||
expire_time: TIMESTAMP + 1,
|
expire_time: TIMESTAMP + 1,
|
||||||
comment: String::new(),
|
comment: String::new(),
|
||||||
}
|
}
|
||||||
.sign_msg_with(&id_key, &id_priv, TIMESTAMP, rng)
|
.sign_msg_with(&id_key, &id_priv, TIMESTAMP, NONCE)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
id_desc.verify(None, TIMESTAMP).unwrap();
|
id_desc.verify(None, TIMESTAMP).unwrap();
|
||||||
|
@ -339,7 +340,7 @@ mod tests {
|
||||||
comment: String::new(),
|
comment: String::new(),
|
||||||
}
|
}
|
||||||
// Self-signed.
|
// Self-signed.
|
||||||
.sign_msg_with(&id_key, &act_priv, TIMESTAMP, rng)
|
.sign_msg_with(&id_key, &act_priv, TIMESTAMP, NONCE)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
assert_err!(
|
assert_err!(
|
||||||
|
@ -353,7 +354,7 @@ mod tests {
|
||||||
comment: String::new(),
|
comment: String::new(),
|
||||||
}
|
}
|
||||||
// Wrong id_key.
|
// Wrong id_key.
|
||||||
.sign_msg_with(&act_pub, &act_priv, TIMESTAMP, rng)
|
.sign_msg_with(&act_pub, &act_priv, TIMESTAMP, NONCE)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_err!(
|
assert_err!(
|
||||||
id_desc.verify(None, TIMESTAMP),
|
id_desc.verify(None, TIMESTAMP),
|
||||||
|
@ -366,7 +367,7 @@ mod tests {
|
||||||
expire_time: u64::MAX,
|
expire_time: u64::MAX,
|
||||||
comment: String::new(),
|
comment: String::new(),
|
||||||
}
|
}
|
||||||
.sign_msg_with(&id_key, &id_priv, TIMESTAMP, rng)
|
.sign_msg_with(&id_key, &id_priv, TIMESTAMP, NONCE)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_err!(
|
assert_err!(
|
||||||
id_desc.verify(None, TIMESTAMP),
|
id_desc.verify(None, TIMESTAMP),
|
||||||
|
@ -379,7 +380,7 @@ mod tests {
|
||||||
expire_time: TIMESTAMP + 1,
|
expire_time: TIMESTAMP + 1,
|
||||||
comment: String::new(),
|
comment: String::new(),
|
||||||
}
|
}
|
||||||
.sign_msg_with(&id_key, &id_priv, TIMESTAMP, rng)
|
.sign_msg_with(&id_key, &id_priv, TIMESTAMP, NONCE)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
id_desc.verify(None, TIMESTAMP).unwrap();
|
id_desc.verify(None, TIMESTAMP).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -500,7 +500,8 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn canonical_msg() {
|
fn canonical_msg() {
|
||||||
let mut fake_rng = rand::rngs::mock::StepRng::new(0x42, 1);
|
const NONCE: u32 = 0x42;
|
||||||
|
|
||||||
let id_key = SigningKey::from_bytes(&[0x42; 32]);
|
let id_key = SigningKey::from_bytes(&[0x42; 32]);
|
||||||
let act_key = SigningKey::from_bytes(&[0x43; 32]);
|
let act_key = SigningKey::from_bytes(&[0x43; 32]);
|
||||||
let timestamp = 0xDEAD_BEEF;
|
let timestamp = 0xDEAD_BEEF;
|
||||||
|
@ -508,12 +509,7 @@ mod tests {
|
||||||
rich_text: RichText::from("hello"),
|
rich_text: RichText::from("hello"),
|
||||||
room: Id(42),
|
room: Id(42),
|
||||||
}
|
}
|
||||||
.sign_msg_with(
|
.sign_msg_with(&id_key.verifying_key().into(), &act_key, timestamp, NONCE)
|
||||||
&id_key.verifying_key().into(),
|
|
||||||
&act_key,
|
|
||||||
timestamp,
|
|
||||||
&mut fake_rng,
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let json = serde_jcs::to_string(&msg).unwrap();
|
let json = serde_jcs::to_string(&msg).unwrap();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue