use crate::core::indexer::code::IndexedSigCode;
use crate::core::matter::code::{SeedCode, SignatureCode, VerKeyCode};
use crate::crypto::error::SignatureError;
use crate::crypto::verify::{verify_ed25519, verify_secp256k1, verify_secp256r1};
mod private {
pub trait Sealed {}
}
pub trait Algorithm: private::Sealed {
const NAME: &'static str;
const SEED_CODE: SeedCode;
const VERKEY_CODE: VerKeyCode;
const VERKEY_CODE_N: VerKeyCode;
const SIGNATURE_CODE: SignatureCode;
const IDX_BOTH: IndexedSigCode;
const IDX_CRT: IndexedSigCode;
const IDX_BOTH_BIG: IndexedSigCode;
const IDX_CRT_BIG: IndexedSigCode;
const SEED_SIZE: usize;
const PUBLIC_KEY_SIZE: usize;
const SIGNATURE_SIZE: usize;
#[must_use]
fn owns_indexed(code: IndexedSigCode) -> bool {
code == Self::IDX_BOTH
|| code == Self::IDX_CRT
|| code == Self::IDX_BOTH_BIG
|| code == Self::IDX_CRT_BIG
}
fn verify_bytes(pubkey: &[u8], data: &[u8], sig: &[u8]) -> Result<(), SignatureError>;
}
pub struct Ed25519;
impl private::Sealed for Ed25519 {}
impl Algorithm for Ed25519 {
const NAME: &'static str = "Ed25519";
const SEED_CODE: SeedCode = SeedCode::Ed25519Seed;
const VERKEY_CODE: VerKeyCode = VerKeyCode::Ed25519;
const VERKEY_CODE_N: VerKeyCode = VerKeyCode::Ed25519N;
const SIGNATURE_CODE: SignatureCode = SignatureCode::Ed25519Sig;
const IDX_BOTH: IndexedSigCode = IndexedSigCode::Ed25519;
const IDX_CRT: IndexedSigCode = IndexedSigCode::Ed25519Crt;
const IDX_BOTH_BIG: IndexedSigCode = IndexedSigCode::Ed25519Big;
const IDX_CRT_BIG: IndexedSigCode = IndexedSigCode::Ed25519BigCrt;
const SEED_SIZE: usize = 32;
const PUBLIC_KEY_SIZE: usize = 32;
const SIGNATURE_SIZE: usize = 64;
fn verify_bytes(pubkey: &[u8], data: &[u8], sig: &[u8]) -> Result<(), SignatureError> {
verify_ed25519(pubkey, data, sig)
}
}
pub struct Secp256k1;
impl private::Sealed for Secp256k1 {}
impl Algorithm for Secp256k1 {
const NAME: &'static str = "Secp256k1";
const SEED_CODE: SeedCode = SeedCode::ECDSA256k1Seed;
const VERKEY_CODE: VerKeyCode = VerKeyCode::ECDSA256k1;
const VERKEY_CODE_N: VerKeyCode = VerKeyCode::ECDSA256k1N;
const SIGNATURE_CODE: SignatureCode = SignatureCode::ECDSA256k1Sig;
const IDX_BOTH: IndexedSigCode = IndexedSigCode::ECDSA256k1;
const IDX_CRT: IndexedSigCode = IndexedSigCode::ECDSA256k1Crt;
const IDX_BOTH_BIG: IndexedSigCode = IndexedSigCode::ECDSA256k1Big;
const IDX_CRT_BIG: IndexedSigCode = IndexedSigCode::ECDSA256k1BigCrt;
const SEED_SIZE: usize = 32;
const PUBLIC_KEY_SIZE: usize = 33;
const SIGNATURE_SIZE: usize = 64;
fn verify_bytes(pubkey: &[u8], data: &[u8], sig: &[u8]) -> Result<(), SignatureError> {
verify_secp256k1(pubkey, data, sig)
}
}
pub struct Secp256r1;
impl private::Sealed for Secp256r1 {}
impl Algorithm for Secp256r1 {
const NAME: &'static str = "Secp256r1";
const SEED_CODE: SeedCode = SeedCode::ECDSA256r1Seed;
const VERKEY_CODE: VerKeyCode = VerKeyCode::ECDSA256r1;
const VERKEY_CODE_N: VerKeyCode = VerKeyCode::ECDSA256r1N;
const SIGNATURE_CODE: SignatureCode = SignatureCode::ECDSA256r1Sig;
const IDX_BOTH: IndexedSigCode = IndexedSigCode::ECDSA256r1;
const IDX_CRT: IndexedSigCode = IndexedSigCode::ECDSA256r1Crt;
const IDX_BOTH_BIG: IndexedSigCode = IndexedSigCode::ECDSA256r1Big;
const IDX_CRT_BIG: IndexedSigCode = IndexedSigCode::ECDSA256r1BigCrt;
const SEED_SIZE: usize = 32;
const PUBLIC_KEY_SIZE: usize = 33;
const SIGNATURE_SIZE: usize = 64;
fn verify_bytes(pubkey: &[u8], data: &[u8], sig: &[u8]) -> Result<(), SignatureError> {
verify_secp256r1(pubkey, data, sig)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::indexer::code::IndexedSigCode;
use crate::core::matter::code::{SeedCode, SignatureCode, VerKeyCode};
#[test]
fn ed25519_constants() {
assert_eq!(Ed25519::SEED_CODE, SeedCode::Ed25519Seed);
assert_eq!(Ed25519::VERKEY_CODE, VerKeyCode::Ed25519);
assert_eq!(Ed25519::VERKEY_CODE_N, VerKeyCode::Ed25519N);
assert_eq!(Ed25519::SIGNATURE_CODE, SignatureCode::Ed25519Sig);
assert_eq!(Ed25519::SEED_SIZE, 32);
assert_eq!(Ed25519::PUBLIC_KEY_SIZE, 32);
assert_eq!(Ed25519::SIGNATURE_SIZE, 64);
}
#[test]
fn secp256k1_constants() {
assert_eq!(Secp256k1::SEED_CODE, SeedCode::ECDSA256k1Seed);
assert_eq!(Secp256k1::VERKEY_CODE, VerKeyCode::ECDSA256k1);
assert_eq!(Secp256k1::VERKEY_CODE_N, VerKeyCode::ECDSA256k1N);
assert_eq!(Secp256k1::SIGNATURE_CODE, SignatureCode::ECDSA256k1Sig);
assert_eq!(Secp256k1::SEED_SIZE, 32);
assert_eq!(Secp256k1::PUBLIC_KEY_SIZE, 33);
assert_eq!(Secp256k1::SIGNATURE_SIZE, 64);
}
#[test]
fn secp256r1_constants() {
assert_eq!(Secp256r1::SEED_CODE, SeedCode::ECDSA256r1Seed);
assert_eq!(Secp256r1::VERKEY_CODE, VerKeyCode::ECDSA256r1);
assert_eq!(Secp256r1::VERKEY_CODE_N, VerKeyCode::ECDSA256r1N);
assert_eq!(Secp256r1::SIGNATURE_CODE, SignatureCode::ECDSA256r1Sig);
assert_eq!(Secp256r1::SEED_SIZE, 32);
assert_eq!(Secp256r1::PUBLIC_KEY_SIZE, 33);
assert_eq!(Secp256r1::SIGNATURE_SIZE, 64);
}
#[test]
fn ed25519_idx_constants() {
assert_eq!(Ed25519::IDX_BOTH, IndexedSigCode::Ed25519);
assert_eq!(Ed25519::IDX_CRT, IndexedSigCode::Ed25519Crt);
assert_eq!(Ed25519::IDX_BOTH_BIG, IndexedSigCode::Ed25519Big);
assert_eq!(Ed25519::IDX_CRT_BIG, IndexedSigCode::Ed25519BigCrt);
}
#[test]
fn secp256k1_idx_constants() {
assert_eq!(Secp256k1::IDX_BOTH, IndexedSigCode::ECDSA256k1);
assert_eq!(Secp256k1::IDX_CRT, IndexedSigCode::ECDSA256k1Crt);
assert_eq!(Secp256k1::IDX_BOTH_BIG, IndexedSigCode::ECDSA256k1Big);
assert_eq!(Secp256k1::IDX_CRT_BIG, IndexedSigCode::ECDSA256k1BigCrt);
}
#[test]
fn secp256r1_idx_constants() {
assert_eq!(Secp256r1::IDX_BOTH, IndexedSigCode::ECDSA256r1);
assert_eq!(Secp256r1::IDX_CRT, IndexedSigCode::ECDSA256r1Crt);
assert_eq!(Secp256r1::IDX_BOTH_BIG, IndexedSigCode::ECDSA256r1Big);
assert_eq!(Secp256r1::IDX_CRT_BIG, IndexedSigCode::ECDSA256r1BigCrt);
}
#[test]
fn owns_indexed_accepts_all_own_variants() {
for code in [
IndexedSigCode::Ed25519,
IndexedSigCode::Ed25519Crt,
IndexedSigCode::Ed25519Big,
IndexedSigCode::Ed25519BigCrt,
] {
assert!(Ed25519::owns_indexed(code), "Ed25519 should own {code:?}");
}
for code in [
IndexedSigCode::ECDSA256k1,
IndexedSigCode::ECDSA256k1Crt,
IndexedSigCode::ECDSA256k1Big,
IndexedSigCode::ECDSA256k1BigCrt,
] {
assert!(
Secp256k1::owns_indexed(code),
"Secp256k1 should own {code:?}"
);
}
for code in [
IndexedSigCode::ECDSA256r1,
IndexedSigCode::ECDSA256r1Crt,
IndexedSigCode::ECDSA256r1Big,
IndexedSigCode::ECDSA256r1BigCrt,
] {
assert!(
Secp256r1::owns_indexed(code),
"Secp256r1 should own {code:?}"
);
}
}
#[test]
fn owns_indexed_rejects_other_algorithms() {
assert!(!Ed25519::owns_indexed(IndexedSigCode::ECDSA256k1));
assert!(!Ed25519::owns_indexed(IndexedSigCode::ECDSA256r1Big));
assert!(!Secp256k1::owns_indexed(IndexedSigCode::Ed25519));
assert!(!Secp256k1::owns_indexed(IndexedSigCode::ECDSA256r1));
assert!(!Secp256r1::owns_indexed(IndexedSigCode::Ed25519Crt));
assert!(!Secp256r1::owns_indexed(IndexedSigCode::ECDSA256k1Big));
}
}