Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
229 changes: 107 additions & 122 deletions Cargo.lock

Large diffs are not rendered by default.

29 changes: 20 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ miden-utils-testing = { path = "./crates/test-utils", package = "miden-test-util
miden-verifier = { path = "./verifier", version = "0.21", default-features = false }

# Miden crates
miden-crypto = { version = "0.20", default-features = false }
miden-crypto = { version = "0.21", default-features = false }
miden-formatting = { version = "0.1", default-features = false }
midenc-hir-type = { version = "0.4", default-features = false }

Expand Down Expand Up @@ -94,16 +94,27 @@ rand = { version = "0.9", default-features = false }
sha2 = { version = "0.10", default-features = false }

# Upstream Plonky3 dependencies
p3-blake3 = { version = "0.4", default-features = false }
p3-commit = { version = "0.4", default-features = false }
p3-dft = { version = "0.4", default-features = false }
p3-keccak = { version = "0.4", default-features = false }
p3-matrix = { version = "0.4", default-features = false }
p3-merkle-tree = { version = "0.4", default-features = false }
p3-air = { version = "0.4.2", default-features = false }
p3-blake3 = { version = "0.4.2", default-features = false }
p3-challenger = { version = "0.4.2", default-features = false }
p3-commit = { version = "0.4.2", default-features = false }
p3-dft = { version = "0.4.2", default-features = false }
p3-field = { version = "0.4.2", default-features = false }
p3-goldilocks = { version = "0.4.2", default-features = false }
p3-interpolation = { version = "0.4.2", default-features = false }
p3-keccak = { version = "0.4.2", default-features = false }
p3-matrix = { version = "0.4.2", default-features = false }
p3-maybe-rayon = { version = "0.4.2", default-features = false }
p3-merkle-tree = { version = "0.4.2", default-features = false }
p3-poseidon2 = { version = "0.4.2", default-features = false }
p3-symmetric = { version = "0.4.2", default-features = false }
p3-uni-stark = { version = "0.4.2", default-features = false }
p3-util = { version = "0.4.2", default-features = false }

# Miden-specific Plonky3 crates
p3-miden-fri = { version = "0.4", default-features = false }
p3-miden-air = { version = "0.4.2", default-features = false }
p3-miden-fri = { version = "0.4.2", default-features = false }
p3-miden-prover = { version = "0.4.2", default-features = false }

# WASM support
getrandom = { version = "0.2", default-features = false, features = ["js"] }

2 changes: 1 addition & 1 deletion core/src/advice/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ mod tests {
#[test]
fn test_advice_map_serialization() {
let mut map1 = AdviceMap::default();
map1.insert(Word::default(), vec![Felt::from(1u32), Felt::from(2u32)]);
map1.insert(Word::default(), vec![Felt::new(1), Felt::new(2)]);

let bytes = map1.to_bytes();

Expand Down
57 changes: 21 additions & 36 deletions core/src/event_id.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use alloc::{borrow::Cow, string::String};
use core::fmt::{Display, Formatter};

use miden_crypto::utils::{
ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
use miden_crypto::{
field::PrimeField64,
utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
Expand All @@ -12,24 +13,26 @@ use crate::{Felt, utils::hash_string_to_word};
// EVENT ID
// ================================================================================================

/// A type-safe wrapper around a [`Felt`] that represents an event identifier.
/// A type-safe event identifier that semantically represents a [`Felt`] value.
///
/// Event IDs are used to identify events that can be emitted by the VM or handled by the host.
/// This newtype provides type safety and ensures that event IDs are not accidentally confused
/// with other [`Felt`] values.
/// with other field element values.
///
/// Internally stored as `u64` rather than [`Felt`] to enable `const` construction.
///
/// [`EventId`] contains only the identifier. For events with human-readable names,
/// use [`EventName`] instead.
///
/// Event IDs are derived from event names using blake3 hashing.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[cfg_attr(
all(feature = "arbitrary", test),
miden_test_serde_macros::serde_test(binary_serde(true))
)]
pub struct EventId(Felt);
pub struct EventId(u64);

impl EventId {
/// Computes the canonical event identifier for the given `name`.
Expand All @@ -39,7 +42,7 @@ impl EventId {
/// 1. Computing the BLAKE3 hash of the event name (produces 32 bytes)
/// 2. Taking the first 8 bytes of the hash
/// 3. Interpreting these bytes as a little-endian u64
/// 4. Reducing modulo the field prime to create a valid Felt
/// 4. Reducing modulo the field prime to produce a valid field element
///
/// Note that this is the same procedure performed by [`hash_string_to_word`], where we take
/// the first element of the resulting [`Word`](crate::Word).
Expand All @@ -48,45 +51,27 @@ impl EventId {
/// providing good distribution properties to minimize collisions between different names.
pub fn from_name(name: impl AsRef<str>) -> Self {
let digest_word = hash_string_to_word(name.as_ref());
Self(digest_word[0])
Self(digest_word[0].as_canonical_u64())
}

/// Creates an EventId from a [`Felt`] value (e.g., from the stack).
pub const fn from_felt(event_id: Felt) -> Self {
Self(event_id)
pub fn from_felt(event_id: Felt) -> Self {
Self(event_id.as_canonical_u64())
}

/// Creates an EventId from a u64, converting it to a [`Felt`].
/// Creates an EventId from a `u64` value, reducing modulo the field prime.
pub const fn from_u64(event_id: u64) -> Self {
Self(Felt::new(event_id))
Self(event_id % Felt::ORDER_U64)
}

/// Returns the underlying [`Felt`] value.
/// Converts this event ID to a [`Felt`].
pub const fn as_felt(&self) -> Felt {
self.0
Felt::new(self.0)
}

/// Returns the underlying `u64` value.
/// Returns the inner `u64` representation.
pub const fn as_u64(&self) -> u64 {
self.0.as_int()
}
}

impl PartialOrd for EventId {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl Ord for EventId {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.0.inner().cmp(&other.0.inner())
}
}

impl core::hash::Hash for EventId {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.0.inner().hash(state);
self.0
}
}

Expand Down Expand Up @@ -164,13 +149,13 @@ impl AsRef<str> for EventName {

impl Serializable for EventId {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.0.write_into(target);
self.as_felt().write_into(target);
}
}

impl Deserializable for EventId {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
Ok(Self(Felt::read_from(source)?))
Ok(Self(Felt::read_from(source)?.as_canonical_u64()))
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl Serializable for Kernel {
impl Deserializable for Kernel {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let len = source.read_u8()? as usize;
let kernel = source.read_many::<Word>(len)?;
let kernel = source.read_many_iter::<Word>(len)?.collect::<Result<_, _>>()?;
Ok(Self(kernel))
}
}
2 changes: 1 addition & 1 deletion core/src/mast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ impl MastForest {
impl MastForest {
/// Given an error code as a Felt, resolves it to its corresponding error message.
pub fn resolve_error_message(&self, code: Felt) -> Option<Arc<str>> {
let key = u64::from(code);
let key = code.as_canonical_u64();
self.debug_info.error_message(key)
}

Expand Down
4 changes: 2 additions & 2 deletions core/src/mast/node/basic_block_node/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::{boxed::Box, string::String, vec::Vec};
use core::{fmt, iter::repeat_n};

use miden_crypto::{Felt, Word, ZERO, hash::blake::Blake3_256};
use miden_crypto::{Felt, Word, ZERO, field::PrimeField64, hash::blake::Blake3_256};
use miden_formatting::prettier::PrettyPrint;

use crate::{
Expand Down Expand Up @@ -1593,7 +1593,7 @@ impl MastForestContributor for BasicBlockNodeBuilder {
// we include the operation index to distinguish between basic blocks that
// would have the same assert instructions, but in a different order
assert_data.extend_from_slice(&op_idx.to_le_bytes());
let inner_value = u64::from(*inner_value);
let inner_value = inner_value.as_canonical_u64();
assert_data.extend_from_slice(&inner_value.to_le_bytes());
}
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/mast/serialization/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fn serialize_deserialize_all_nodes() {
let basic_block_id = {
let operations = vec![
Operation::Noop,
Operation::Assert(Felt::from(42u32)),
Operation::Assert(Felt::new(42)),
Operation::SDepth,
Operation::Caller,
Operation::Clk,
Expand Down Expand Up @@ -166,7 +166,7 @@ fn serialize_deserialize_all_nodes() {
Operation::Ext2Mul,
Operation::U32split,
Operation::U32add,
Operation::U32assert2(Felt::from(222u32)),
Operation::U32assert2(Felt::new(222)),
Operation::U32add3,
Operation::U32sub,
Operation::U32mul,
Expand Down Expand Up @@ -219,7 +219,7 @@ fn serialize_deserialize_all_nodes() {
Operation::MStream,
Operation::Pipe,
Operation::HPerm,
Operation::MpVerify(Felt::from(1022u32)),
Operation::MpVerify(Felt::new(1022)),
Operation::MrUpdate,
Operation::FriE2F4,
Operation::HornerBase,
Expand Down
4 changes: 3 additions & 1 deletion core/src/stack/inputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ impl Deserializable for StackInputs {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let num_elements = source.read_u8()?;

let mut elements = source.read_many::<Felt>(num_elements.into())?;
let mut elements = source
.read_many_iter::<Felt>(num_elements.into())?
.collect::<Result<Vec<_>, _>>()?;
elements.reverse();

StackInputs::new(elements).map_err(|err| {
Expand Down
3 changes: 2 additions & 1 deletion core/src/stack/outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ impl Deserializable for StackOutputs {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let num_elements = source.read_u8()?;

let elements = source.read_many::<Felt>(num_elements.into())?;
let elements =
source.read_many_iter::<Felt>(num_elements.into())?.collect::<Result<_, _>>()?;

StackOutputs::new(elements).map_err(|err| {
DeserializationError::InvalidValue(format!("failed to create stack outputs: {err}",))
Expand Down
20 changes: 9 additions & 11 deletions core/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@ use core::{

mod col_matrix;
pub use col_matrix::ColMatrix;
// RE-EXPORTS
// ================================================================================================
use miden_crypto::field::{PrimeCharacteristicRing, PrimeField64};
#[cfg(feature = "std")]
pub use miden_crypto::utils::ReadAdapter;
// RE-EXPORTS
// ================================================================================================
pub use miden_crypto::{
hash::blake::{Blake3_256, Blake3Digest},
utils::{
ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable, SliceReader,
flatten_slice_elements, flatten_vector_elements, group_slice_elements, uninit_vector,
group_slice_elements, uninit_vector,
},
};
pub use miden_formatting::hex::{DisplayHex, ToHex, to_hex};

use crate::{
Felt, Word,
field::{PrimeCharacteristicRing, PrimeField64},
};
use crate::{Felt, Word};

pub mod math {
pub use miden_crypto::field::batch_multiplicative_inverse as batch_inversion;
Expand Down Expand Up @@ -172,10 +170,10 @@ const BYTES_PER_U32: usize = core::mem::size_of::<u32>();
///
/// # Examples
/// ```
/// # use miden_core::{Felt, utils::bytes_to_packed_u32_elements};
/// # use miden_core::{Felt, field::PrimeCharacteristicRing, utils::bytes_to_packed_u32_elements};
/// let bytes = vec![0x01, 0x02, 0x03, 0x04, 0x05];
/// let felts = bytes_to_packed_u32_elements(&bytes);
/// assert_eq!(felts, vec![Felt::from(0x04030201_u32), Felt::from(0x00000005_u32)]);
/// assert_eq!(felts, vec![Felt::new(0x04030201), Felt::new(0x00000005)]);
/// ```
pub fn bytes_to_packed_u32_elements(bytes: &[u8]) -> Vec<Felt> {
bytes
Expand All @@ -184,7 +182,7 @@ pub fn bytes_to_packed_u32_elements(bytes: &[u8]) -> Vec<Felt> {
// Pack up to 4 bytes into a u32 in little-endian format
let mut packed = [0u8; BYTES_PER_U32];
packed[..chunk.len()].copy_from_slice(chunk);
Felt::from(u32::from_le_bytes(packed))
Felt::from_u32(u32::from_le_bytes(packed))
})
.collect()
}
Expand Down Expand Up @@ -231,7 +229,7 @@ mod tests {
#[test]
fn proptest_packed_u32_elements_roundtrip(values in prop::collection::vec(any::<u32>(), 0..100)) {
// Convert u32 values to Felts
let felts: Vec<Felt> = values.iter().map(|&v| Felt::from(v)).collect();
let felts: Vec<Felt> = values.iter().map(|&v| Felt::from_u32(v)).collect();

// Roundtrip: Felts -> bytes -> Felts
let bytes = packed_u32_elements_to_bytes(&felts);
Expand Down
2 changes: 1 addition & 1 deletion crates/assembly-syntax/src/ast/instruction/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ mod tests {
let target = InvocationTarget::MastRoot(Span::unknown(digest));
let instruction = format!("{}", Instruction::Exec(target));
assert_eq!(
"exec.0x6998a9e7f13f7e81edcabdbc895ec0141f8ce3e7abd061f1370852c082a028fa",
"exec.0x122746acc6fe1310cb4b91cf0ea135cf42b67d94069046ad325ffa2475f0ec8a",
instruction
);
}
Expand Down
2 changes: 1 addition & 1 deletion crates/assembly-syntax/src/parser/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ impl crate::prettier::PrettyPrint for IntValue {
Self::U8(v) => v.render(),
Self::U16(v) => v.render(),
Self::U32(v) => v.render(),
Self::Felt(v) => u64::from(*v).render(),
Self::Felt(v) => v.as_canonical_u64().render(),
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions crates/assembly/src/fmp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use alloc::vec::Vec;

use miden_core::{FMP_ADDR, FMP_INIT_VALUE, Felt, Operation, WORD_SIZE};
use miden_core::{
FMP_ADDR, FMP_INIT_VALUE, Felt, Operation, WORD_SIZE, field::PrimeCharacteristicRing,
};

use crate::push_value_ops;

Expand All @@ -24,7 +26,7 @@ pub(crate) fn fmp_initialization_sequence() -> Vec<Operation> {
/// The number of locals is rounded up to the nearest multiple of the word size to ensure the frame
/// pointer is always word-aligned for operations that require it.
pub(crate) fn fmp_start_frame_sequence(num_locals: u16) -> Vec<Operation> {
let locals_frame = Felt::from(num_locals.next_multiple_of(WORD_SIZE as u16));
let locals_frame = Felt::from_u16(num_locals.next_multiple_of(WORD_SIZE as u16));

[Operation::Push(locals_frame)]
.into_iter()
Expand All @@ -40,7 +42,7 @@ pub(crate) fn fmp_start_frame_sequence(num_locals: u16) -> Vec<Operation> {
/// The number of locals is rounded up to the nearest multiple of the word size to ensure the frame
/// pointer is always word-aligned for operations that require it.
pub(crate) fn fmp_end_frame_sequence(num_locals: u16) -> Vec<Operation> {
let locals_frame = Felt::from(num_locals.next_multiple_of(WORD_SIZE as u16));
let locals_frame = Felt::from_u16(num_locals.next_multiple_of(WORD_SIZE as u16));

[Operation::Push(-locals_frame)]
.into_iter()
Expand Down
2 changes: 1 addition & 1 deletion crates/assembly/src/instruction/crypto_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub(super) fn hash(block_builder: &mut BasicBlockBuilder) {
let ops = [
// add 4 elements to the stack to be used as the capacity elements for the RPO permutation.
// Since we are hashing 4 field elements, the first capacity element is set to 4.
Push(Felt::from(4_u32)), Pad, Pad, Pad,
Push(Felt::new(4)), Pad, Pad, Pad,

// swap capacity elements such that they are below the elements to be hashed
SwapW,
Expand Down
2 changes: 1 addition & 1 deletion crates/assembly/src/instruction/field_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub fn pow2(span_builder: &mut BasicBlockBuilder) {
/// VM cycles: 16 cycles
pub fn append_pow2_op(span_builder: &mut BasicBlockBuilder) {
// push base 2 onto the stack: [exp, ...] -> [2, exp, ...]
span_builder.push_op(Push(2_u8.into()));
span_builder.push_op(Push(Felt::new(2)));
// introduce initial value of acc onto the stack: [2, exp, ...] -> [1, 2, exp, ...]
span_builder.push_ops([Pad, Incr]);
// arrange the top of the stack for EXPACC operation: [1, 2, exp, ...] -> [0, 2, 1, exp, ...]
Expand Down
Loading
Loading