use std::{cmp::Ordering, fmt, str::FromStr};
use anyhow::anyhow;
use derive_more::{AsRef, Deref, From, Into};
use ed25519_dalek::{SignatureError, Signer, SigningKey, Verifier, VerifyingKey};
use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize};
use willow_store::{FixedSize, IsLowerBound, LowerBound};
use super::meadowcap::IsCommunal;
pub const PUBLIC_KEY_LENGTH: usize = ed25519_dalek::PUBLIC_KEY_LENGTH;
pub const SECRET_KEY_LENGTH: usize = ed25519_dalek::SECRET_KEY_LENGTH;
pub const SIGNATURE_LENGTH: usize = ed25519_dalek::SIGNATURE_LENGTH;
macro_rules! bytestring {
($ty:ty, $n:ident) => {
impl $ty {
pub const LENGTH: usize = $n;
pub fn fmt_short(&self) -> String {
data_encoding::HEXLOWER.encode(&(self.to_bytes()[..10]))
}
}
impl fmt::Display for $ty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", data_encoding::HEXLOWER.encode(&self.to_bytes()))
}
}
impl fmt::Debug for $ty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}({})", stringify!($ty), self.fmt_short())
}
}
};
}
impl IsCommunal for NamespaceId {
fn is_communal(&self) -> bool {
self.as_bytes()[31] == 0
}
}
impl IsCommunal for NamespacePublicKey {
fn is_communal(&self) -> bool {
self.id().is_communal()
}
}
#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
pub enum NamespaceKind {
Communal,
Owned,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct NamespaceSecretKey(SigningKey);
bytestring!(NamespaceSecretKey, PUBLIC_KEY_LENGTH);
impl NamespaceSecretKey {
pub fn generate<R: CryptoRngCore + ?Sized>(rng: &mut R, typ: NamespaceKind) -> Self {
loop {
let signing_key = SigningKey::generate(rng);
let secret_key = NamespaceSecretKey(signing_key);
if secret_key.public_key().kind() == typ {
break secret_key;
}
}
}
pub fn from_bytes(bytes: &[u8; 32]) -> Self {
SigningKey::from_bytes(bytes).into()
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}
pub fn public_key(&self) -> NamespacePublicKey {
NamespacePublicKey(self.0.verifying_key())
}
pub fn id(&self) -> NamespaceId {
NamespaceId::from(self.public_key())
}
pub fn sign(&self, msg: &[u8]) -> NamespaceSignature {
NamespaceSignature(self.0.sign(msg))
}
pub fn verify(&self, msg: &[u8], signature: &NamespaceSignature) -> Result<(), SignatureError> {
self.0.verify_strict(msg, &signature.0)
}
}
#[derive(Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Hash, derive_more::From)]
pub struct NamespacePublicKey(VerifyingKey);
bytestring!(NamespacePublicKey, PUBLIC_KEY_LENGTH);
impl NamespacePublicKey {
pub fn kind(&self) -> NamespaceKind {
if self.is_communal() {
NamespaceKind::Communal
} else {
NamespaceKind::Owned
}
}
pub fn verify(&self, msg: &[u8], signature: &NamespaceSignature) -> Result<(), SignatureError> {
self.0.verify_strict(msg, &signature.0)
}
pub fn as_bytes(&self) -> &[u8; 32] {
self.0.as_bytes()
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}
pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self, SignatureError> {
Ok(NamespacePublicKey(VerifyingKey::from_bytes(bytes)?))
}
pub fn id(&self) -> NamespaceId {
self.into()
}
}
#[derive(Clone, Serialize, Deserialize)]
pub struct UserSecretKey(SigningKey);
bytestring!(UserSecretKey, SECRET_KEY_LENGTH);
impl UserSecretKey {
pub fn generate<R: CryptoRngCore + ?Sized>(rng: &mut R) -> Self {
let signing_key = SigningKey::generate(rng);
UserSecretKey(signing_key)
}
pub fn from_bytes(bytes: &[u8; 32]) -> Self {
SigningKey::from_bytes(bytes).into()
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}
pub fn public_key(&self) -> UserPublicKey {
UserPublicKey(self.0.verifying_key())
}
pub fn id(&self) -> UserId {
UserId::from(self.public_key())
}
pub fn sign(&self, msg: &[u8]) -> UserSignature {
UserSignature(self.0.sign(msg))
}
pub fn verify(&self, msg: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
self.0.verify_strict(msg, &signature.0)
}
}
#[derive(Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash, derive_more::From)]
pub struct UserPublicKey(VerifyingKey);
bytestring!(UserPublicKey, PUBLIC_KEY_LENGTH);
impl UserPublicKey {
pub fn verify(&self, msg: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
self.0.verify_strict(msg, &signature.0)
}
pub fn as_bytes(&self) -> &[u8; 32] {
self.0.as_bytes()
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}
pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self, SignatureError> {
Ok(UserPublicKey(VerifyingKey::from_bytes(bytes)?))
}
pub fn id(&self) -> UserId {
self.into()
}
}
impl FromStr for UserSecretKey {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::from_bytes(
&data_encoding::BASE32_NOPAD
.decode(s.as_ref())
.map_err(|_| anyhow!("Failed to decode base32: {s}"))?
.try_into()
.map_err(|s: Vec<u8>| {
anyhow!(
"Incorrect size for UserSecretKey, expected 32 bytes, got {}",
s.len()
)
})?,
))
}
}
impl FromStr for NamespaceSecretKey {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::from_bytes(
&data_encoding::BASE32_NOPAD
.decode(s.as_ref())
.map_err(|_| anyhow!("Failed to decode base32: {s}"))?
.try_into()
.map_err(|s: Vec<u8>| {
anyhow!(
"Incorrect size for NamespaceSecretKey, expected 32 bytes, got {}",
s.len()
)
})?,
))
}
}
impl FromStr for UserPublicKey {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::from_bytes(
&data_encoding::BASE32_NOPAD
.decode(s.as_ref())
.map_err(|_| anyhow!("Failed to decode base32: {s}"))?
.try_into()
.map_err(|s: Vec<u8>| {
anyhow!(
"Incorrect size for UserPublicKey, expected 32 bytes, got {}",
s.len()
)
})?,
)?)
}
}
impl FromStr for NamespacePublicKey {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::from_bytes(
&data_encoding::BASE32_NOPAD
.decode(s.as_ref())
.map_err(|_| anyhow!("Failed to decode base32: {s}"))?
.try_into()
.map_err(|s: Vec<u8>| {
anyhow!(
"Incorrect size for NamespacePublicKey, expected 32 bytes, got {}",
s.len()
)
})?,
)?)
}
}
impl From<SigningKey> for UserSecretKey {
fn from(signing_key: SigningKey) -> Self {
Self(signing_key)
}
}
impl From<SigningKey> for NamespaceSecretKey {
fn from(signing_key: SigningKey) -> Self {
Self(signing_key)
}
}
impl PartialOrd for NamespacePublicKey {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for NamespacePublicKey {
fn cmp(&self, other: &Self) -> Ordering {
self.0.as_bytes().cmp(other.0.as_bytes())
}
}
impl PartialOrd for UserPublicKey {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for UserPublicKey {
fn cmp(&self, other: &Self) -> Ordering {
self.0.as_bytes().cmp(other.0.as_bytes())
}
}
impl From<NamespaceSecretKey> for NamespacePublicKey {
fn from(value: NamespaceSecretKey) -> Self {
value.public_key()
}
}
impl From<UserSecretKey> for UserPublicKey {
fn from(value: UserSecretKey) -> Self {
value.public_key()
}
}
impl From<&NamespaceSecretKey> for NamespacePublicKey {
fn from(value: &NamespaceSecretKey) -> Self {
value.public_key()
}
}
impl From<&UserSecretKey> for UserPublicKey {
fn from(value: &UserSecretKey) -> Self {
value.public_key()
}
}
#[derive(Serialize, Deserialize, Clone, From, PartialEq, Eq, Deref)]
pub struct NamespaceSignature(ed25519_dalek::Signature);
impl NamespaceSignature {
pub fn from_bytes(bytes: [u8; SIGNATURE_LENGTH]) -> Self {
Self(ed25519_dalek::Signature::from_bytes(&bytes))
}
}
impl PartialOrd for NamespaceSignature {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for NamespaceSignature {
fn cmp(&self, other: &Self) -> Ordering {
self.to_bytes().cmp(&other.to_bytes())
}
}
bytestring!(NamespaceSignature, SIGNATURE_LENGTH);
impl std::hash::Hash for NamespaceSignature {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.to_bytes().hash(state);
}
}
#[derive(Serialize, Deserialize, Clone, From, PartialEq, Eq, Deref)]
pub struct UserSignature(ed25519_dalek::Signature);
impl UserSignature {
pub fn from_bytes(bytes: [u8; SIGNATURE_LENGTH]) -> Self {
Self(ed25519_dalek::Signature::from_bytes(&bytes))
}
}
impl PartialOrd for UserSignature {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for UserSignature {
fn cmp(&self, other: &Self) -> Ordering {
self.to_bytes().cmp(&other.to_bytes())
}
}
bytestring!(UserSignature, SIGNATURE_LENGTH);
impl std::hash::Hash for UserSignature {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.to_bytes().hash(state);
}
}
#[derive(
Default,
Clone,
Copy,
PartialOrd,
Ord,
Eq,
PartialEq,
Hash,
From,
Into,
AsRef,
Serialize,
Deserialize,
zerocopy_derive::FromBytes,
zerocopy_derive::AsBytes,
zerocopy_derive::FromZeroes,
)]
#[repr(transparent)]
pub struct UserId([u8; 32]);
impl LowerBound for UserId {
fn min_value() -> Self {
Self([0u8; 32])
}
}
impl IsLowerBound for UserId {
fn is_min_value(&self) -> bool {
*self == Self::min_value()
}
}
impl FixedSize for UserId {
const SIZE: usize = std::mem::size_of::<Self>();
}
bytestring!(UserId, PUBLIC_KEY_LENGTH);
impl UserId {
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0
}
pub fn into_public_key(&self) -> Result<UserPublicKey, SignatureError> {
UserPublicKey::from_bytes(&self.0)
}
pub fn from_bytes_unchecked(bytes: [u8; 32]) -> Self {
Self(bytes)
}
}
#[derive(
Default,
Clone,
Copy,
PartialOrd,
Ord,
Eq,
PartialEq,
Hash,
From,
Into,
AsRef,
Serialize,
Deserialize,
)]
pub struct NamespaceId([u8; 32]);
bytestring!(NamespaceId, PUBLIC_KEY_LENGTH);
impl NamespaceId {
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0
}
pub fn into_public_key(&self) -> Result<NamespacePublicKey, SignatureError> {
NamespacePublicKey::from_bytes(&self.0)
}
pub fn from_bytes_unchecked(bytes: [u8; 32]) -> Self {
Self(bytes)
}
}
impl AsRef<[u8]> for NamespaceId {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl AsRef<[u8]> for UserId {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl From<UserPublicKey> for UserId {
fn from(value: UserPublicKey) -> Self {
Self(*value.as_bytes())
}
}
impl From<NamespacePublicKey> for NamespaceId {
fn from(value: NamespacePublicKey) -> Self {
Self(*value.as_bytes())
}
}
impl From<&UserPublicKey> for UserId {
fn from(value: &UserPublicKey) -> Self {
Self(*value.as_bytes())
}
}
impl From<&NamespacePublicKey> for NamespaceId {
fn from(value: &NamespacePublicKey) -> Self {
Self(*value.as_bytes())
}
}
impl From<UserSecretKey> for UserId {
fn from(value: UserSecretKey) -> Self {
value.id()
}
}
impl From<NamespaceSecretKey> for NamespaceId {
fn from(value: NamespaceSecretKey) -> Self {
value.id()
}
}
impl TryFrom<NamespaceId> for NamespacePublicKey {
type Error = SignatureError;
fn try_from(value: NamespaceId) -> Result<Self, Self::Error> {
Self::from_bytes(&value.0)
}
}
impl TryFrom<UserId> for UserPublicKey {
type Error = SignatureError;
fn try_from(value: UserId) -> Result<Self, Self::Error> {
Self::from_bytes(&value.0)
}
}
impl FromStr for UserId {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
UserPublicKey::from_str(s).map(|x| x.into())
}
}
impl FromStr for NamespaceId {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
NamespacePublicKey::from_str(s).map(|x| x.into())
}
}
mod willow_impls {
use super::*;
use crate::util::increment_by_one;
impl willow_data_model::SubspaceId for UserId {
fn successor(&self) -> Option<Self> {
increment_by_one(self.as_bytes()).map(Self::from_bytes_unchecked)
}
}
impl willow_data_model::SubspaceId for UserPublicKey {
fn successor(&self) -> Option<Self> {
match increment_by_one(self.as_bytes()) {
Some(bytes) => Self::from_bytes(&bytes).ok(),
None => None,
}
}
}
impl willow_data_model::NamespaceId for NamespaceId {}
impl willow_data_model::NamespaceId for NamespacePublicKey {}
impl Verifier<UserSignature> for UserPublicKey {
fn verify(
&self,
msg: &[u8],
signature: &UserSignature,
) -> Result<(), ed25519_dalek::ed25519::Error> {
self.0.verify(msg, &signature.0)
}
}
impl Verifier<UserSignature> for UserId {
fn verify(
&self,
msg: &[u8],
signature: &UserSignature,
) -> Result<(), ed25519_dalek::ed25519::Error> {
let key = self.into_public_key()?;
key.0.verify(msg, &signature.0)
}
}
impl Verifier<NamespaceSignature> for NamespacePublicKey {
fn verify(
&self,
msg: &[u8],
signature: &NamespaceSignature,
) -> Result<(), ed25519_dalek::ed25519::Error> {
self.0.verify(msg, &signature.0)
}
}
impl Verifier<NamespaceSignature> for NamespaceId {
fn verify(
&self,
msg: &[u8],
signature: &NamespaceSignature,
) -> Result<(), ed25519_dalek::ed25519::Error> {
let key = self.into_public_key()?;
key.0.verify(msg, &signature.0)
}
}
impl Signer<UserSignature> for UserSecretKey {
fn try_sign(&self, msg: &[u8]) -> Result<UserSignature, ed25519_dalek::ed25519::Error> {
Ok(UserSignature(self.0.sign(msg)))
}
}
impl Signer<NamespaceSignature> for NamespaceSecretKey {
fn try_sign(
&self,
msg: &[u8],
) -> Result<NamespaceSignature, ed25519_dalek::ed25519::Error> {
Ok(NamespaceSignature(self.0.sign(msg)))
}
}
}
use syncify::{syncify, syncify_replace};
#[syncify(encoding_sync)]
mod encoding {
#[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)]
use ufotofu::local_nb::{BulkConsumer, BulkProducer};
use willow_encoding::DecodeError;
#[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)]
use willow_encoding::{Decodable, Encodable};
use super::*;
impl Encodable for NamespacePublicKey {
async fn encode<Consumer>(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error>
where
Consumer: BulkConsumer<Item = u8>,
{
consumer
.bulk_consume_full_slice(self.as_bytes())
.await
.map_err(|err| err.reason)
}
}
impl Encodable for UserPublicKey {
async fn encode<Consumer>(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error>
where
Consumer: BulkConsumer<Item = u8>,
{
consumer
.bulk_consume_full_slice(self.as_bytes())
.await
.map_err(|err| err.reason)
}
}
impl Encodable for NamespaceSignature {
async fn encode<Consumer>(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error>
where
Consumer: BulkConsumer<Item = u8>,
{
consumer
.bulk_consume_full_slice(&self.to_bytes())
.await
.map_err(|err| err.reason)
}
}
impl Encodable for UserSignature {
async fn encode<Consumer>(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error>
where
Consumer: BulkConsumer<Item = u8>,
{
consumer
.bulk_consume_full_slice(&self.to_bytes())
.await
.map_err(|err| err.reason)
}
}
impl Encodable for UserId {
async fn encode<Consumer>(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error>
where
Consumer: BulkConsumer<Item = u8>,
{
consumer
.bulk_consume_full_slice(self.as_bytes())
.await
.map_err(|err| err.reason)
}
}
impl Encodable for NamespaceId {
async fn encode<Consumer>(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error>
where
Consumer: BulkConsumer<Item = u8>,
{
consumer
.bulk_consume_full_slice(self.as_bytes())
.await
.map_err(|err| err.reason)
}
}
impl Decodable for NamespaceId {
async fn decode<Producer>(
producer: &mut Producer,
) -> Result<Self, DecodeError<Producer::Error>>
where
Producer: BulkProducer<Item = u8>,
{
let mut bytes = [0; PUBLIC_KEY_LENGTH];
producer.bulk_overwrite_full_slice(&mut bytes).await?;
Ok(Self::from_bytes_unchecked(bytes))
}
}
impl Decodable for UserId {
async fn decode<Producer>(
producer: &mut Producer,
) -> Result<Self, DecodeError<Producer::Error>>
where
Producer: BulkProducer<Item = u8>,
{
let mut bytes = [0; PUBLIC_KEY_LENGTH];
producer.bulk_overwrite_full_slice(&mut bytes).await?;
Ok(Self::from_bytes_unchecked(bytes))
}
}
impl Decodable for NamespaceSignature {
async fn decode<Producer>(
producer: &mut Producer,
) -> Result<Self, DecodeError<Producer::Error>>
where
Producer: BulkProducer<Item = u8>,
{
let mut bytes = [0; SIGNATURE_LENGTH];
producer.bulk_overwrite_full_slice(&mut bytes).await?;
Ok(Self::from_bytes(bytes))
}
}
impl Decodable for UserSignature {
async fn decode<Producer>(
producer: &mut Producer,
) -> Result<Self, DecodeError<Producer::Error>>
where
Producer: BulkProducer<Item = u8>,
{
let mut bytes = [0; SIGNATURE_LENGTH];
producer.bulk_overwrite_full_slice(&mut bytes).await?;
Ok(Self::from_bytes(bytes))
}
}
}