Skip to content

Commit

Permalink
Merge pull request #43 from int08h/dalek
Browse files Browse the repository at this point in the history
Refactor signing and verification to use ed25519-dalek
  • Loading branch information
int08h authored Oct 12, 2024
2 parents dad0919 + 52e5a04 commit 33d1e44
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 45 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ yaml-rust = "0.4"
zeroize = "1.8"
data-encoding = "2.6"
enum-iterator = "2.1"
ed25519-dalek = "2.1"

# Used by 'awskms' and 'gcpkms'
futures = { version = "^0.3", optional = true }
Expand Down
4 changes: 2 additions & 2 deletions src/bin/roughenough-client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use ring::rand;
use ring::rand::SecureRandom;
use roughenough::key::LongTermKey;
use roughenough::merkle::MerkleTree;
use roughenough::sign::Verifier;
use roughenough::sign::MsgVerifier;
use roughenough::version::Version;
use roughenough::{
roughenough_version, Error, RtMessage, Tag, CERTIFICATE_CONTEXT, REQUEST_FRAMING_BYTES,
Expand Down Expand Up @@ -314,7 +314,7 @@ impl ResponseHandler {
}

fn validate_sig(&self, public_key: &[u8], sig: &[u8], data: &[u8]) -> bool {
let mut verifier = Verifier::new(public_key);
let mut verifier = MsgVerifier::new(public_key);
verifier.update(data);
verifier.verify(sig)
}
Expand Down
10 changes: 5 additions & 5 deletions src/key/longterm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use crate::key::OnlineKey;
use crate::message::RtMessage;
use crate::sign::Signer;
use crate::sign::MsgSigner;
use crate::tag::Tag;
use crate::CERTIFICATE_CONTEXT;
use ring::digest;
Expand All @@ -30,7 +30,7 @@ use std::fmt::Formatter;
/// Represents the server's long-term identity.
///
pub struct LongTermKey {
signer: Signer,
signer: MsgSigner,
srv_value: Vec<u8>,
}

Expand All @@ -43,8 +43,8 @@ impl LongTermKey {
}

pub fn new(seed: &[u8]) -> Self {
let signer = Signer::from_seed(seed);
let srv_value = LongTermKey::calc_srv_value(signer.public_key_bytes());
let signer = MsgSigner::from_seed(seed);
let srv_value = LongTermKey::calc_srv_value(&signer.public_key_bytes());

LongTermKey {
signer,
Expand All @@ -70,7 +70,7 @@ impl LongTermKey {
}

/// Return the public key for the provided seed
pub fn public_key(&self) -> &[u8] {
pub fn public_key(&self) -> Vec<u8> {
self.signer.public_key_bytes()
}

Expand Down
8 changes: 4 additions & 4 deletions src/key/online.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use byteorder::{LittleEndian, WriteBytesExt};

use crate::message::RtMessage;
use crate::sign::Signer;
use crate::sign::MsgSigner;
use crate::tag::Tag;
use crate::version::Version;
use crate::SIGNED_RESPONSE_CONTEXT;
Expand All @@ -28,7 +28,7 @@ use crate::SIGNED_RESPONSE_CONTEXT;
/// Represents the delegated Roughtime ephemeral online key.
///
pub struct OnlineKey {
signer: Signer,
signer: MsgSigner,
}

impl Default for OnlineKey {
Expand All @@ -40,7 +40,7 @@ impl Default for OnlineKey {
impl OnlineKey {
pub fn new() -> Self {
OnlineKey {
signer: Signer::new(),
signer: MsgSigner::new(),
}
}

Expand All @@ -51,7 +51,7 @@ impl OnlineKey {
let pub_key_bytes = self.signer.public_key_bytes();

let mut dele_msg = RtMessage::with_capacity(3);
dele_msg.add_field(Tag::PUBK, pub_key_bytes).unwrap();
dele_msg.add_field(Tag::PUBK, &pub_key_bytes).unwrap();
dele_msg.add_field(Tag::MINT, &zeros).unwrap();
dele_msg.add_field(Tag::MAXT, &max).unwrap();

Expand Down
5 changes: 2 additions & 3 deletions src/responder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ use data_encoding::{Encoding, HEXLOWER_PERMISSIVE};
use mio::net::UdpSocket;

use crate::config::ServerConfig;
use crate::error::Error::SendingResponseFailed;
use crate::grease::Grease;
use crate::key::{LongTermKey, OnlineKey};
use crate::merkle::MerkleTree;
use crate::stats::ServerStats;
use crate::version::Version;
use crate::{Error, RtMessage, Tag};
use crate::{RtMessage, Tag};

const HEX: Encoding = HEXLOWER_PERMISSIVE;

Expand All @@ -50,7 +49,7 @@ impl Responder {
pub fn new(version: Version, config: &dyn ServerConfig, ltk: &mut LongTermKey) -> Responder {
let online_key = OnlineKey::new();
let cert_bytes = ltk.make_cert(&online_key).encode().expect("make_cert");
let long_term_public_key = HEX.encode(ltk.public_key());
let long_term_public_key = HEX.encode(&ltk.public_key());
let requests = Vec::with_capacity(config.batch_size() as usize);
let grease = Grease::new(config.fault_percentage());
let thread_id = thread::current().name().unwrap().to_string();
Expand Down
63 changes: 32 additions & 31 deletions src/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use std::fmt;
use std::fmt::Formatter;

use data_encoding::{Encoding, HEXLOWER_PERMISSIVE};
use ed25519_dalek::{SigningKey, Signature, Verifier, Signer, VerifyingKey, SecretKey};
use ring::rand::SecureRandom;
use ring::signature::{self, Ed25519KeyPair, KeyPair};
use ring::rand;

const HEX: Encoding = HEXLOWER_PERMISSIVE;
Expand All @@ -30,58 +30,58 @@ const INITIAL_BUF_SIZE: usize = 1024;

/// A multi-step (init-update-finish) interface for verifying an Ed25519 signature
#[derive(Debug)]
pub struct Verifier {
pubkey: Vec<u8>,
pub struct MsgVerifier {
pubkey: VerifyingKey,
buf: Vec<u8>,
}

impl Verifier {
impl MsgVerifier {
pub fn new(pubkey: &[u8]) -> Self {
Verifier {
pubkey: Vec::from(pubkey),
let pk: &[u8; 32] = pubkey.try_into().expect("valid pubkey");
MsgVerifier {
pubkey: VerifyingKey::from_bytes(pk).unwrap(),
buf: Vec::with_capacity(INITIAL_BUF_SIZE),
}
}

pub fn update(&mut self, data: &[u8]) {
self.buf.reserve(data.len());
self.buf.extend_from_slice(data);
}

pub fn verify(&self, expected_sig: &[u8]) -> bool {
let pk = signature::UnparsedPublicKey::new(&signature::ED25519, &self.pubkey);

match pk.verify(&self.buf, expected_sig) {
pub fn verify(&self, provided_sig: &[u8]) -> bool {
let sig = Signature::from_slice(provided_sig).expect("valid signature");
match self.pubkey.verify(&self.buf, &sig) {
Ok(_) => true,
_ => false,
}
}
}

/// A multi-step (init-update-finish) interface for creating an Ed25519 signature
pub struct Signer {
key_pair: Ed25519KeyPair,
pub struct MsgSigner {
signing_key: SigningKey,
buf: Vec<u8>,
}

impl Default for Signer {
impl Default for MsgSigner {
fn default() -> Self {
Self::new()
}
}

impl Signer {
impl MsgSigner {
pub fn new() -> Self {
let rng = rand::SystemRandom::new();
let mut seed = [0u8; 32];
rng.fill(&mut seed).unwrap();

Signer::from_seed(&seed)
MsgSigner::from_seed(&seed)
}

pub fn from_seed(seed: &[u8]) -> Self {
Signer {
key_pair: Ed25519KeyPair::from_seed_unchecked(seed).unwrap(),
let secret_key = SecretKey::try_from(seed).expect("invalid seed");
MsgSigner {
signing_key: SigningKey::from(secret_key),
buf: Vec::with_capacity(INITIAL_BUF_SIZE),
}
}
Expand All @@ -92,29 +92,30 @@ impl Signer {
}

pub fn sign(&mut self) -> Vec<u8> {
let signature = self.key_pair.sign(&self.buf).as_ref().to_vec();
let signature = self.signing_key.sign(&self.buf).to_vec();
self.buf.clear();

signature
}

pub fn public_key_bytes(&self) -> &[u8] {
self.key_pair.public_key().as_ref()
pub fn public_key_bytes(&self) -> Vec<u8> {
let binding = self.signing_key.verifying_key();
binding.as_bytes().to_vec()
}
}

impl fmt::Display for Signer {
impl fmt::Display for MsgSigner {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", HEX.encode(self.public_key_bytes()))
write!(f, "{}", HEX.encode(&self.public_key_bytes()))
}
}

impl fmt::Debug for Signer {
impl fmt::Debug for MsgSigner {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(
f,
"Signer({}, {:?})",
HEX.encode(self.public_key_bytes()),
HEX.encode(&self.public_key_bytes()),
self.buf
)
}
Expand All @@ -135,7 +136,7 @@ mod test {
"e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".as_ref()
).unwrap();

let v = Verifier::new(&pubkey);
let v = MsgVerifier::new(&pubkey);
let result = v.verify(&signature);
assert_eq!(result, true);
}
Expand All @@ -152,7 +153,7 @@ mod test {
"124f6fc6b0d100842769e71bd530664d888df8507df6c56dedfdb509aeb93416e26b918d38aa06305df3095697c18b2aa832eaa52edc0ae49fbae5a85e150c07".as_ref()
).unwrap();

let mut v = Verifier::new(&pubkey);
let mut v = MsgVerifier::new(&pubkey);
v.update(&message);
let result = v.verify(&signature);
assert_eq!(result, true);
Expand All @@ -167,7 +168,7 @@ mod test {
"e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".as_ref()
).unwrap();

let mut s = Signer::from_seed(&seed);
let mut s = MsgSigner::from_seed(&seed);
let sig = s.sign();
assert_eq!(sig, expected_sig);
}
Expand All @@ -183,7 +184,7 @@ mod test {
"d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00c".as_ref()
).unwrap();

let mut s = Signer::from_seed(&seed);
let mut s = MsgSigner::from_seed(&seed);
s.update(&message);
let sig = s.sign();
assert_eq!(sig, expected_sig);
Expand All @@ -196,11 +197,11 @@ mod test {

let message = "Hello world".as_bytes();

let mut signer = Signer::from_seed(&seed);
let mut signer = MsgSigner::from_seed(&seed);
signer.update(&message);
let signature = signer.sign();

let mut v = Verifier::new(signer.public_key_bytes());
let mut v = MsgVerifier::new(&signer.public_key_bytes());
v.update(&message);
let result = v.verify(&signature);

Expand Down

0 comments on commit 33d1e44

Please sign in to comment.