use core::cmp::Ordering;
use miden_core::{
Felt,
deferred::{Digest, Tag},
};
use miden_precompiles::{CurvePrecompile, Keccak256Precompile, UintDomain, UintPrecompile};
use crate::transcript::nodes::{EcOpId, UINT_PIN_CLAIM_TAG, UintOpId};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct P2Digest(pub [Felt; 4]);
impl P2Digest {
pub fn as_array(&self) -> [Felt; 4] {
self.0
}
}
impl PartialOrd for P2Digest {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for P2Digest {
fn cmp(&self, other: &Self) -> Ordering {
self.0
.map(|felt| felt.as_canonical_u64())
.cmp(&other.0.map(|felt| felt.as_canonical_u64()))
}
}
impl From<Digest> for P2Digest {
fn from(digest: Digest) -> Self {
Self(digest.into_elements())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct P2Cap(pub [Felt; 4]);
impl P2Cap {
pub fn as_array(&self) -> [Felt; 4] {
self.0
}
pub fn chunk() -> Self {
Self(Tag::CHUNKS.as_word())
}
pub fn and() -> Self {
Self(Tag::AND.as_word())
}
pub fn keccak256_assertion(len_bytes: u32) -> Self {
Self(Keccak256Precompile::assert_tag(len_bytes).as_word())
}
pub fn uint_value(bound_ptr: u32) -> Self {
let domain = UintDomain::from_bound_ptr(bound_ptr).expect("known uint bound pointer");
Self(UintPrecompile::value_tag(domain).as_word())
}
pub fn uint_pin_claim(bound_ptr: u32, pin_ptr: u32) -> Self {
Self([
Felt::from(UINT_PIN_CLAIM_TAG),
Felt::from(bound_ptr),
Felt::from(pin_ptr),
Felt::ZERO,
])
}
pub fn uint_op(op: UintOpId) -> Self {
let op_id = match op {
UintOpId::Add => UintPrecompile::ADD_OP_ID,
UintOpId::Sub => UintPrecompile::SUB_OP_ID,
UintOpId::Mul => UintPrecompile::MUL_OP_ID,
UintOpId::Is => UintPrecompile::EQ_OP_ID,
};
Self(UintPrecompile::op_tag(op_id).as_word())
}
pub fn ec_create(group_ptr: u32) -> Self {
Self([
CurvePrecompile::id(),
Felt::from_u32(CurvePrecompile::VALUE_OP_ID as u32),
Felt::from(group_ptr),
Felt::ZERO,
])
}
pub fn ec_op(op: EcOpId) -> Self {
let op_id = match op {
EcOpId::Add => CurvePrecompile::ADD_OP_ID,
EcOpId::Sub => CurvePrecompile::SUB_OP_ID,
EcOpId::Is => CurvePrecompile::EQ_OP_ID,
};
Self([CurvePrecompile::id(), Felt::from_u32(op_id as u32), Felt::ZERO, Felt::ZERO])
}
pub fn ec_msm_iv() -> Self {
Self([
CurvePrecompile::id(),
Felt::from_u32(CurvePrecompile::MSM_OP_ID as u32),
Felt::ZERO,
Felt::ZERO,
])
}
}