use crate::{
core::{
actually_used_field::ActuallyUsedField,
bounds::{BoolBounds, Bounds, CurveBounds, FieldBounds},
circuits::boolean::byte::Byte,
expressions::expr::EvalValue,
},
traits::FromLeBytes,
utils::{
crypto::key::{
AES_128_KEY_COUNT,
AES_192_KEY_COUNT,
AES_256_KEY_COUNT,
ED25519_SECRET_KEY_COUNT,
ED25519_SIGNING_KEY_HASH_PREFIX_COUNT,
ED25519_VERIFYING_KEY_COUNT,
MXE_AES128_KEY,
MXE_AES192_KEY,
MXE_AES256_KEY,
MXE_ED25519_SECRET_KEY,
MXE_ED25519_SIGNING_KEY_HASH_PREFIX,
MXE_ED25519_SIGNING_KEY_S,
MXE_ED25519_VERIFYING_KEY,
MXE_ELGAMAL_PUBKEY,
MXE_ELGAMAL_SECRET_KEY,
MXE_RESCUE_BASE_FIELD_KEY,
MXE_X25519_PRIVATE_KEY,
RESCUE_KEY_COUNT,
},
curve_point::CurvePoint,
field::{BaseField, ScalarField},
},
};
use curve25519_dalek_arcium_fork::ristretto::CompressedRistretto;
use serde::{Deserialize, Serialize};
use std::marker::PhantomData;
pub trait ArxInput {
type Output;
fn is_plaintext(&self) -> bool;
fn mock_eval(&self) -> Self::Output;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MxeInput {
Bit(MxeBitInput),
ScalarOnly(MxeScalarInput),
Scalar(MxeFieldInput<ScalarField>),
Base(MxeFieldInput<BaseField>),
Curve(MxeCurveInput),
}
impl MxeInput {
pub fn bounds(&self) -> Bounds {
match self {
MxeInput::Bit(_) => Bounds::Bit(BoolBounds::new(true, true)),
MxeInput::ScalarOnly(_) => Bounds::Scalar(FieldBounds::All),
MxeInput::Scalar(i) => Bounds::Scalar(i.bounds()),
MxeInput::Base(i) => Bounds::Base(i.bounds()),
MxeInput::Curve(_) => Bounds::Curve(CurveBounds::All),
}
}
}
impl ArxInput for MxeInput {
type Output = EvalValue;
fn is_plaintext(&self) -> bool {
match self {
MxeInput::Bit(i) => i.is_plaintext(),
MxeInput::ScalarOnly(i) => i.is_plaintext(),
MxeInput::Scalar(i) => i.is_plaintext(),
MxeInput::Base(i) => i.is_plaintext(),
MxeInput::Curve(i) => i.is_plaintext(),
}
}
fn mock_eval(&self) -> Self::Output {
match self {
MxeInput::Bit(i) => EvalValue::Bit(i.mock_eval()),
MxeInput::ScalarOnly(i) => EvalValue::Scalar(i.mock_eval()),
MxeInput::Scalar(i) => EvalValue::Scalar(i.mock_eval()),
MxeInput::Base(i) => EvalValue::Base(i.mock_eval()),
MxeInput::Curve(i) => EvalValue::Curve(i.mock_eval()),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MxeBitInput {
AES128Key(usize),
AES192Key(usize),
AES256Key(usize),
Ed25519SecretKey(usize),
Ed25519SigningKeyHashPrefix(usize),
}
impl ArxInput for MxeBitInput {
type Output = bool;
fn is_plaintext(&self) -> bool {
false
}
fn mock_eval(&self) -> Self::Output {
match *self {
MxeBitInput::AES128Key(i) => {
if i < AES_128_KEY_COUNT {
Byte::from(MXE_AES128_KEY[i / 8]).get_bits()[i % 8]
} else {
false
}
}
MxeBitInput::AES192Key(i) => {
if i < AES_192_KEY_COUNT {
Byte::from(MXE_AES192_KEY[i / 8]).get_bits()[i % 8]
} else {
false
}
}
MxeBitInput::AES256Key(i) => {
if i < AES_256_KEY_COUNT {
Byte::from(MXE_AES256_KEY[i / 8]).get_bits()[i % 8]
} else {
false
}
}
MxeBitInput::Ed25519SecretKey(i) => {
if i < ED25519_SECRET_KEY_COUNT {
Byte::from(MXE_ED25519_SECRET_KEY[i / 8]).get_bits()[i % 8]
} else {
false
}
}
MxeBitInput::Ed25519SigningKeyHashPrefix(i) => {
if i < ED25519_SIGNING_KEY_HASH_PREFIX_COUNT {
Byte::from(MXE_ED25519_SIGNING_KEY_HASH_PREFIX[i / 8]).get_bits()[i % 8]
} else {
false
}
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MxeScalarInput {
X25519PrivateKey(),
Ed25519SigningKeyS(),
ElGamalSecretKey(),
}
impl ArxInput for MxeScalarInput {
type Output = ScalarField;
fn is_plaintext(&self) -> bool {
false
}
fn mock_eval(&self) -> Self::Output {
match self {
MxeScalarInput::X25519PrivateKey() => {
ScalarField::from_le_bytes(MXE_X25519_PRIVATE_KEY)
}
MxeScalarInput::Ed25519SigningKeyS() => {
ScalarField::from_le_bytes(MXE_ED25519_SIGNING_KEY_S)
}
MxeScalarInput::ElGamalSecretKey() => {
ScalarField::from_le_bytes(MXE_ELGAMAL_SECRET_KEY)
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MxeFieldInput<F: ActuallyUsedField> {
Ed25519VerifyingKey(usize),
RescueKey(usize),
Phantom(PhantomData<F>),
}
impl<F: ActuallyUsedField> MxeFieldInput<F> {
pub fn bounds(&self) -> FieldBounds<F> {
match self {
MxeFieldInput::Ed25519VerifyingKey(_) => FieldBounds::new(F::ZERO, F::from(255)),
MxeFieldInput::RescueKey(_) => FieldBounds::All,
MxeFieldInput::Phantom(_) => {
panic!("Phantom type cannot be created.")
}
}
}
}
impl<F: ActuallyUsedField> ArxInput for MxeFieldInput<F> {
type Output = F;
fn is_plaintext(&self) -> bool {
match self {
MxeFieldInput::Ed25519VerifyingKey(_) => true,
MxeFieldInput::RescueKey(_) => false,
MxeFieldInput::Phantom(_) => {
panic!("Phantom type is not supported")
}
}
}
fn mock_eval(&self) -> F {
match *self {
MxeFieldInput::Ed25519VerifyingKey(i) => {
if i < ED25519_VERIFYING_KEY_COUNT {
F::from(MXE_ED25519_VERIFYING_KEY[i] as u64)
} else {
F::ZERO
}
}
MxeFieldInput::RescueKey(i) => {
if i < RESCUE_KEY_COUNT {
F::from_le_bytes(MXE_RESCUE_BASE_FIELD_KEY[i])
} else {
F::ZERO
}
}
MxeFieldInput::Phantom(_) => {
panic!("Phantom type is not supported")
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MxeCurveInput {
ElGamalPubkey(),
}
impl ArxInput for MxeCurveInput {
type Output = CurvePoint;
fn is_plaintext(&self) -> bool {
true
}
fn mock_eval(&self) -> CurvePoint {
match self {
MxeCurveInput::ElGamalPubkey() => {
let point = CompressedRistretto::from_slice(&MXE_ELGAMAL_PUBKEY)
.unwrap()
.decompress()
.unwrap();
CurvePoint::new(point)
}
}
}
}