SIGMA-I Key Exchange (#378)
* Move `KeGroup` to `KeyExchange::Group` - Introduce `KeyExchange::Hash`, which separates the OPRF hash from the one used in `KeyExchange`. - Remove `De/Serialize` requirement on key exchange messages and states, which forced a lot of where bounds on downstream users. - Rename `KeGroup` to `Group`. - Replace `D` generic for hash with `H`. * Use `voprf::derive_key()` directly * Implement SIGMA-I key exchange * Improve `KeyExchange` for SIGMA-I and Ed25519 * Implement EdDSA * Un-qualify some method calls * SIGMA-I: only include client identity in client mac * SIGMA-I: include server mac in client signature * Expose key exchange types in `crate` & move modules * Implement Ed25519ph * Document `ed25519` crate feature * Remove `ristretto255-voprf` crate feature * Adjust CI crate feature testing * Fix Rustdoc * Remove unnecessary generic parameters from SIGMA-I * Properly mark to-do's with TODO * Assorted fixes * SIGMA-I: include context in signature * SIGMA-I: include identifiers in signature * Merge `ServerLoginStart/FinishParameters` * Re-export more necessary types * More carefully expose types * Add ECDSA test * SIGMA-I: share context hashing * De-duplicate client static public key storage * Hide `KeyExchange` better * Use the correct hash in the root documentation * Bump `derive-where` * Format documentation examples a bit further * Add remote OPRF seed documentation * Rename `deserialize_key_pair` to `deserialize_take_key_pair` * Add more key tests * Remove `SharedSecret` trait * SIGMA-I refactor message API * Share more implementation between 3DH and SIGMA-I * Remove unnecessary zero scalar check for Curve25519 * Use correct hash in test * Add some more TODOs * Exclude `tests` folder from Cargo publishing * Enable missing dependencies * Use right crate for testing Ed25519 * Remove unnecessary `Sized` constraints * Remove unnecessary `ecdsa` crate features * Move signature de/serialization to trait methods * Nit: move import to appropriate location * Add warning to SIGMA-I
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
//
|
||||
// This source code is dual-licensed under either the MIT license found in the
|
||||
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
// of this source tree. You may select, at your option, one of the above-listed
|
||||
// licenses.
|
||||
|
||||
//! HashEdDSA implementation for [`SigmaI`](crate::SigmaI). Currently only
|
||||
//! supports [`Ed25519`](crate::Ed25519).
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use generic_array::GenericArray;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use self::implementation::HashEddsaImpl;
|
||||
use super::{Message, MessageBuilder, SignatureProtocol};
|
||||
use crate::ciphersuite::CipherSuite;
|
||||
use crate::errors::ProtocolError;
|
||||
use crate::key_exchange::group::Group;
|
||||
|
||||
/// HashEdDSA for [`SigmaI`](crate::SigmaI).
|
||||
///
|
||||
/// The ["verification state"](Self::VerifyState) is the pre-hash for the
|
||||
/// message to be verified.
|
||||
pub struct HashEddsa<G>(PhantomData<G>);
|
||||
|
||||
impl<G: HashEddsaImpl> SignatureProtocol for HashEddsa<G> {
|
||||
type Group = G;
|
||||
type Signature = G::Signature;
|
||||
type SignatureLen = G::SignatureLen;
|
||||
type VerifyState<CS: CipherSuite, KE: Group> = G::VerifyState<CS, KE>;
|
||||
|
||||
fn sign<'a, R: CryptoRng + RngCore, CS: CipherSuite, KE: Group>(
|
||||
sk: &<Self::Group as Group>::Sk,
|
||||
_: &mut R,
|
||||
message: &Message<CS, KE>,
|
||||
) -> (Self::Signature, Self::VerifyState<CS, KE>) {
|
||||
G::sign(sk, message)
|
||||
}
|
||||
|
||||
fn verify<CS: CipherSuite, KE: Group>(
|
||||
pk: &<Self::Group as Group>::Pk,
|
||||
_: MessageBuilder<'_, CS>,
|
||||
state: Self::VerifyState<CS, KE>,
|
||||
signature: &Self::Signature,
|
||||
) -> Result<(), ProtocolError> {
|
||||
G::verify(pk, state, signature)
|
||||
}
|
||||
|
||||
fn serialize_signature(signature: &Self::Signature) -> GenericArray<u8, Self::SignatureLen> {
|
||||
G::serialize_signature(signature)
|
||||
}
|
||||
|
||||
fn deserialize_take_signature(bytes: &mut &[u8]) -> Result<Self::Signature, ProtocolError> {
|
||||
G::deserialize_take_signature(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
pub(in super::super) mod implementation {
|
||||
use generic_array::ArrayLength;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub trait HashEddsaImpl: Group {
|
||||
type Signature: Clone + Zeroize;
|
||||
type SignatureLen: ArrayLength<u8>;
|
||||
type VerifyState<CS: CipherSuite, KE: Group>: Clone + Zeroize;
|
||||
|
||||
fn sign<CS: CipherSuite, KE: Group>(
|
||||
sk: &Self::Sk,
|
||||
message: &Message<CS, KE>,
|
||||
) -> (Self::Signature, Self::VerifyState<CS, KE>);
|
||||
|
||||
fn verify<CS: CipherSuite, KE: Group>(
|
||||
pk: &Self::Pk,
|
||||
state: Self::VerifyState<CS, KE>,
|
||||
signature: &Self::Signature,
|
||||
) -> Result<(), ProtocolError>;
|
||||
|
||||
fn deserialize_take_signature(bytes: &mut &[u8]) -> Result<Self::Signature, ProtocolError>;
|
||||
|
||||
fn serialize_signature(signature: &Self::Signature)
|
||||
-> GenericArray<u8, Self::SignatureLen>;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user