1use alloc::{string::String, vec::Vec};
4use core::{
5 cmp::Ordering,
6 fmt::Display,
7 hash::{Hash, Hasher},
8 ops::{Deref, DerefMut, Index, IndexMut, Range},
9 slice,
10};
11
12use thiserror::Error;
13use winter_crypto::Digest;
14use winter_math::FieldElement;
15
16const WORD_SIZE_FELT: usize = 4;
17const WORD_SIZE_BYTES: usize = 32;
18
19use super::{Felt, StarkField, ZERO};
20use crate::{
21 rand::Randomizable,
22 utils::{
23 ByteReader, ByteWriter, Deserializable, DeserializationError, HexParseError, Serializable,
24 bytes_to_hex_string, hex_to_bytes,
25 },
26};
27
28mod lexicographic;
29pub use lexicographic::LexicographicWord;
30
31#[cfg(test)]
32mod tests;
33
34#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
39#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
40#[cfg_attr(feature = "serde", serde(into = "String", try_from = "&str"))]
41pub struct Word([Felt; WORD_SIZE_FELT]);
42
43impl Word {
44 pub const SERIALIZED_SIZE: usize = WORD_SIZE_BYTES;
46
47 pub const fn new(value: [Felt; WORD_SIZE_FELT]) -> Self {
49 Self(value)
50 }
51
52 pub const fn parse(hex: &str) -> Result<Self, &'static str> {
68 const fn parse_hex_digit(digit: u8) -> Result<u8, &'static str> {
69 match digit {
70 b'0'..=b'9' => Ok(digit - b'0'),
71 b'A'..=b'F' => Ok(digit - b'A' + 0x0a),
72 b'a'..=b'f' => Ok(digit - b'a' + 0x0a),
73 _ => Err("Invalid hex character"),
74 }
75 }
76 let hex_bytes = match hex.as_bytes() {
78 [b'0', b'x', rest @ ..] => rest,
79 _ => return Err("Hex string must have a \"0x\" prefix"),
80 };
81
82 if hex_bytes.len() > 64 {
83 return Err("Hex string has more than 64 characters");
84 }
85
86 let mut felts = [0u64; 4];
87 let mut i = 0;
88 while i < hex_bytes.len() {
89 let hex_digit = match parse_hex_digit(hex_bytes[i]) {
90 Ok(v) => v as u64,
93 Err(e) => return Err(e),
94 };
95
96 let inibble = if i.is_multiple_of(2) {
99 (i + 1) % 16
100 } else {
101 (i - 1) % 16
102 };
103
104 let value = hex_digit << (inibble * 4);
105 felts[i / 2 / 8] += value;
106
107 i += 1;
108 }
109
110 let mut idx = 0;
113 while idx < felts.len() {
114 if felts[idx] >= Felt::MODULUS {
115 return Err("Felt overflow");
116 }
117 idx += 1;
118 }
119
120 Ok(Self::new([
121 Felt::new(felts[0]),
122 Felt::new(felts[1]),
123 Felt::new(felts[2]),
124 Felt::new(felts[3]),
125 ]))
126 }
127
128 pub const fn empty() -> Self {
130 Self([Felt::ZERO; WORD_SIZE_FELT])
131 }
132
133 pub const fn is_empty(&self) -> bool {
135 const ZERO_FELT_INNER: u64 = Felt::ZERO.inner();
136
137 self.0[0].inner() == ZERO_FELT_INNER
138 && self.0[1].inner() == ZERO_FELT_INNER
139 && self.0[2].inner() == ZERO_FELT_INNER
140 && self.0[3].inner() == ZERO_FELT_INNER
141 }
142
143 pub fn as_elements(&self) -> &[Felt] {
145 self.as_ref()
146 }
147
148 pub fn as_bytes(&self) -> [u8; WORD_SIZE_BYTES] {
150 let mut result = [0; WORD_SIZE_BYTES];
151
152 result[..8].copy_from_slice(&self.0[0].as_int().to_le_bytes());
153 result[8..16].copy_from_slice(&self.0[1].as_int().to_le_bytes());
154 result[16..24].copy_from_slice(&self.0[2].as_int().to_le_bytes());
155 result[24..].copy_from_slice(&self.0[3].as_int().to_le_bytes());
156
157 result
158 }
159
160 pub(crate) fn words_as_elements_iter<'a, I>(words: I) -> impl Iterator<Item = &'a Felt>
162 where
163 I: Iterator<Item = &'a Self>,
164 {
165 words.flat_map(|d| d.0.iter())
166 }
167
168 pub fn words_as_elements(words: &[Self]) -> &[Felt] {
170 let p = words.as_ptr();
171 let len = words.len() * WORD_SIZE_FELT;
172 unsafe { slice::from_raw_parts(p as *const Felt, len) }
173 }
174
175 pub fn to_hex(&self) -> String {
177 bytes_to_hex_string(self.as_bytes())
178 }
179
180 pub fn to_vec(&self) -> Vec<Felt> {
182 self.0.to_vec()
183 }
184}
185
186impl Hash for Word {
187 fn hash<H: Hasher>(&self, state: &mut H) {
188 state.write(&self.as_bytes());
189 }
190}
191
192impl Digest for Word {
193 fn as_bytes(&self) -> [u8; WORD_SIZE_BYTES] {
194 self.as_bytes()
195 }
196}
197
198impl Deref for Word {
199 type Target = [Felt; WORD_SIZE_FELT];
200
201 fn deref(&self) -> &Self::Target {
202 &self.0
203 }
204}
205
206impl DerefMut for Word {
207 fn deref_mut(&mut self) -> &mut Self::Target {
208 &mut self.0
209 }
210}
211
212impl Index<usize> for Word {
213 type Output = Felt;
214
215 fn index(&self, index: usize) -> &Self::Output {
216 &self.0[index]
217 }
218}
219
220impl IndexMut<usize> for Word {
221 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
222 &mut self.0[index]
223 }
224}
225
226impl Index<Range<usize>> for Word {
227 type Output = [Felt];
228
229 fn index(&self, index: Range<usize>) -> &Self::Output {
230 &self.0[index]
231 }
232}
233
234impl IndexMut<Range<usize>> for Word {
235 fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
236 &mut self.0[index]
237 }
238}
239
240impl Ord for Word {
241 fn cmp(&self, other: &Self) -> Ordering {
242 self.0.iter().map(Felt::inner).zip(other.0.iter().map(Felt::inner)).fold(
255 Ordering::Equal,
256 |ord, (a, b)| match ord {
257 Ordering::Equal => a.cmp(&b),
258 _ => ord,
259 },
260 )
261 }
262}
263
264impl PartialOrd for Word {
265 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
266 Some(self.cmp(other))
267 }
268}
269
270impl Display for Word {
271 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
272 write!(f, "{}", self.to_hex())
273 }
274}
275
276impl Randomizable for Word {
277 const VALUE_SIZE: usize = WORD_SIZE_BYTES;
278
279 fn from_random_bytes(bytes: &[u8]) -> Option<Self> {
280 let bytes_array: Option<[u8; 32]> = bytes.try_into().ok();
281 if let Some(bytes_array) = bytes_array {
282 Self::try_from(bytes_array).ok()
283 } else {
284 None
285 }
286 }
287}
288
289#[derive(Debug, Error)]
294pub enum WordError {
295 #[error("hex encoded values of a word are invalid")]
297 HexParse(#[from] HexParseError),
298 #[error("failed to convert to field element: {0}")]
300 InvalidFieldElement(String),
301 #[error("invalid input length: expected {1} {0}, but received {2}")]
303 InvalidInputLength(&'static str, usize, usize),
304 #[error("failed to convert the word's field elements to type {0}")]
306 TypeConversion(&'static str),
307}
308
309impl TryFrom<&Word> for [bool; WORD_SIZE_FELT] {
310 type Error = WordError;
311
312 fn try_from(value: &Word) -> Result<Self, Self::Error> {
313 (*value).try_into()
314 }
315}
316
317impl TryFrom<Word> for [bool; WORD_SIZE_FELT] {
318 type Error = WordError;
319
320 fn try_from(value: Word) -> Result<Self, Self::Error> {
321 fn to_bool(v: u64) -> Option<bool> {
322 if v <= 1 { Some(v == 1) } else { None }
323 }
324
325 Ok([
326 to_bool(value.0[0].as_int()).ok_or(WordError::TypeConversion("bool"))?,
327 to_bool(value.0[1].as_int()).ok_or(WordError::TypeConversion("bool"))?,
328 to_bool(value.0[2].as_int()).ok_or(WordError::TypeConversion("bool"))?,
329 to_bool(value.0[3].as_int()).ok_or(WordError::TypeConversion("bool"))?,
330 ])
331 }
332}
333
334impl TryFrom<&Word> for [u8; WORD_SIZE_FELT] {
335 type Error = WordError;
336
337 fn try_from(value: &Word) -> Result<Self, Self::Error> {
338 (*value).try_into()
339 }
340}
341
342impl TryFrom<Word> for [u8; WORD_SIZE_FELT] {
343 type Error = WordError;
344
345 fn try_from(value: Word) -> Result<Self, Self::Error> {
346 Ok([
347 value.0[0].as_int().try_into().map_err(|_| WordError::TypeConversion("u8"))?,
348 value.0[1].as_int().try_into().map_err(|_| WordError::TypeConversion("u8"))?,
349 value.0[2].as_int().try_into().map_err(|_| WordError::TypeConversion("u8"))?,
350 value.0[3].as_int().try_into().map_err(|_| WordError::TypeConversion("u8"))?,
351 ])
352 }
353}
354
355impl TryFrom<&Word> for [u16; WORD_SIZE_FELT] {
356 type Error = WordError;
357
358 fn try_from(value: &Word) -> Result<Self, Self::Error> {
359 (*value).try_into()
360 }
361}
362
363impl TryFrom<Word> for [u16; WORD_SIZE_FELT] {
364 type Error = WordError;
365
366 fn try_from(value: Word) -> Result<Self, Self::Error> {
367 Ok([
368 value.0[0].as_int().try_into().map_err(|_| WordError::TypeConversion("u16"))?,
369 value.0[1].as_int().try_into().map_err(|_| WordError::TypeConversion("u16"))?,
370 value.0[2].as_int().try_into().map_err(|_| WordError::TypeConversion("u16"))?,
371 value.0[3].as_int().try_into().map_err(|_| WordError::TypeConversion("u16"))?,
372 ])
373 }
374}
375
376impl TryFrom<&Word> for [u32; WORD_SIZE_FELT] {
377 type Error = WordError;
378
379 fn try_from(value: &Word) -> Result<Self, Self::Error> {
380 (*value).try_into()
381 }
382}
383
384impl TryFrom<Word> for [u32; WORD_SIZE_FELT] {
385 type Error = WordError;
386
387 fn try_from(value: Word) -> Result<Self, Self::Error> {
388 Ok([
389 value.0[0].as_int().try_into().map_err(|_| WordError::TypeConversion("u32"))?,
390 value.0[1].as_int().try_into().map_err(|_| WordError::TypeConversion("u32"))?,
391 value.0[2].as_int().try_into().map_err(|_| WordError::TypeConversion("u32"))?,
392 value.0[3].as_int().try_into().map_err(|_| WordError::TypeConversion("u32"))?,
393 ])
394 }
395}
396
397impl From<&Word> for [u64; WORD_SIZE_FELT] {
398 fn from(value: &Word) -> Self {
399 (*value).into()
400 }
401}
402
403impl From<Word> for [u64; WORD_SIZE_FELT] {
404 fn from(value: Word) -> Self {
405 [
406 value.0[0].as_int(),
407 value.0[1].as_int(),
408 value.0[2].as_int(),
409 value.0[3].as_int(),
410 ]
411 }
412}
413
414impl From<&Word> for [Felt; WORD_SIZE_FELT] {
415 fn from(value: &Word) -> Self {
416 (*value).into()
417 }
418}
419
420impl From<Word> for [Felt; WORD_SIZE_FELT] {
421 fn from(value: Word) -> Self {
422 value.0
423 }
424}
425
426impl From<&Word> for [u8; WORD_SIZE_BYTES] {
427 fn from(value: &Word) -> Self {
428 (*value).into()
429 }
430}
431
432impl From<Word> for [u8; WORD_SIZE_BYTES] {
433 fn from(value: Word) -> Self {
434 value.as_bytes()
435 }
436}
437
438impl From<&Word> for String {
439 fn from(value: &Word) -> Self {
441 (*value).into()
442 }
443}
444
445impl From<Word> for String {
446 fn from(value: Word) -> Self {
448 value.to_hex()
449 }
450}
451
452impl From<&[bool; WORD_SIZE_FELT]> for Word {
456 fn from(value: &[bool; WORD_SIZE_FELT]) -> Self {
457 (*value).into()
458 }
459}
460
461impl From<[bool; WORD_SIZE_FELT]> for Word {
462 fn from(value: [bool; WORD_SIZE_FELT]) -> Self {
463 [value[0] as u32, value[1] as u32, value[2] as u32, value[3] as u32].into()
464 }
465}
466
467impl From<&[u8; WORD_SIZE_FELT]> for Word {
468 fn from(value: &[u8; WORD_SIZE_FELT]) -> Self {
469 (*value).into()
470 }
471}
472
473impl From<[u8; WORD_SIZE_FELT]> for Word {
474 fn from(value: [u8; WORD_SIZE_FELT]) -> Self {
475 Self([value[0].into(), value[1].into(), value[2].into(), value[3].into()])
476 }
477}
478
479impl From<&[u16; WORD_SIZE_FELT]> for Word {
480 fn from(value: &[u16; WORD_SIZE_FELT]) -> Self {
481 (*value).into()
482 }
483}
484
485impl From<[u16; WORD_SIZE_FELT]> for Word {
486 fn from(value: [u16; WORD_SIZE_FELT]) -> Self {
487 Self([value[0].into(), value[1].into(), value[2].into(), value[3].into()])
488 }
489}
490
491impl From<&[u32; WORD_SIZE_FELT]> for Word {
492 fn from(value: &[u32; WORD_SIZE_FELT]) -> Self {
493 (*value).into()
494 }
495}
496
497impl From<[u32; WORD_SIZE_FELT]> for Word {
498 fn from(value: [u32; WORD_SIZE_FELT]) -> Self {
499 Self([value[0].into(), value[1].into(), value[2].into(), value[3].into()])
500 }
501}
502
503impl TryFrom<&[u64; WORD_SIZE_FELT]> for Word {
504 type Error = WordError;
505
506 fn try_from(value: &[u64; WORD_SIZE_FELT]) -> Result<Self, WordError> {
507 (*value).try_into()
508 }
509}
510
511impl TryFrom<[u64; WORD_SIZE_FELT]> for Word {
512 type Error = WordError;
513
514 fn try_from(value: [u64; WORD_SIZE_FELT]) -> Result<Self, WordError> {
515 Ok(Self([
516 value[0].try_into().map_err(WordError::InvalidFieldElement)?,
517 value[1].try_into().map_err(WordError::InvalidFieldElement)?,
518 value[2].try_into().map_err(WordError::InvalidFieldElement)?,
519 value[3].try_into().map_err(WordError::InvalidFieldElement)?,
520 ]))
521 }
522}
523
524impl From<&[Felt; WORD_SIZE_FELT]> for Word {
525 fn from(value: &[Felt; WORD_SIZE_FELT]) -> Self {
526 Self(*value)
527 }
528}
529
530impl From<[Felt; WORD_SIZE_FELT]> for Word {
531 fn from(value: [Felt; WORD_SIZE_FELT]) -> Self {
532 Self(value)
533 }
534}
535
536impl TryFrom<&[u8; WORD_SIZE_BYTES]> for Word {
537 type Error = WordError;
538
539 fn try_from(value: &[u8; WORD_SIZE_BYTES]) -> Result<Self, Self::Error> {
540 (*value).try_into()
541 }
542}
543
544impl TryFrom<[u8; WORD_SIZE_BYTES]> for Word {
545 type Error = WordError;
546
547 fn try_from(value: [u8; WORD_SIZE_BYTES]) -> Result<Self, Self::Error> {
548 let a = u64::from_le_bytes(value[0..8].try_into().unwrap());
551 let b = u64::from_le_bytes(value[8..16].try_into().unwrap());
552 let c = u64::from_le_bytes(value[16..24].try_into().unwrap());
553 let d = u64::from_le_bytes(value[24..32].try_into().unwrap());
554
555 let a: Felt = a.try_into().map_err(WordError::InvalidFieldElement)?;
556 let b: Felt = b.try_into().map_err(WordError::InvalidFieldElement)?;
557 let c: Felt = c.try_into().map_err(WordError::InvalidFieldElement)?;
558 let d: Felt = d.try_into().map_err(WordError::InvalidFieldElement)?;
559
560 Ok(Word([a, b, c, d]))
561 }
562}
563
564impl TryFrom<&[u8]> for Word {
565 type Error = WordError;
566
567 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
568 let value: [u8; WORD_SIZE_BYTES] = value
569 .try_into()
570 .map_err(|_| WordError::InvalidInputLength("bytes", WORD_SIZE_BYTES, value.len()))?;
571 value.try_into()
572 }
573}
574
575impl TryFrom<&[Felt]> for Word {
576 type Error = WordError;
577
578 fn try_from(value: &[Felt]) -> Result<Self, Self::Error> {
579 let value: [Felt; WORD_SIZE_FELT] = value
580 .try_into()
581 .map_err(|_| WordError::InvalidInputLength("elements", WORD_SIZE_FELT, value.len()))?;
582 Ok(value.into())
583 }
584}
585
586impl TryFrom<&str> for Word {
587 type Error = WordError;
588
589 fn try_from(value: &str) -> Result<Self, Self::Error> {
591 hex_to_bytes::<WORD_SIZE_BYTES>(value)
592 .map_err(WordError::HexParse)
593 .and_then(Word::try_from)
594 }
595}
596
597impl TryFrom<String> for Word {
598 type Error = WordError;
599
600 fn try_from(value: String) -> Result<Self, Self::Error> {
602 value.as_str().try_into()
603 }
604}
605
606impl TryFrom<&String> for Word {
607 type Error = WordError;
608
609 fn try_from(value: &String) -> Result<Self, Self::Error> {
611 value.as_str().try_into()
612 }
613}
614
615impl Serializable for Word {
619 fn write_into<W: ByteWriter>(&self, target: &mut W) {
620 target.write_bytes(&self.as_bytes());
621 }
622
623 fn get_size_hint(&self) -> usize {
624 Self::SERIALIZED_SIZE
625 }
626}
627
628impl Deserializable for Word {
629 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
630 let mut inner: [Felt; WORD_SIZE_FELT] = [ZERO; WORD_SIZE_FELT];
631 for inner in inner.iter_mut() {
632 let e = source.read_u64()?;
633 if e >= Felt::MODULUS {
634 return Err(DeserializationError::InvalidValue(String::from(
635 "value not in the appropriate range",
636 )));
637 }
638 *inner = Felt::new(e);
639 }
640
641 Ok(Self(inner))
642 }
643}
644
645impl IntoIterator for Word {
648 type Item = Felt;
649 type IntoIter = <[Felt; 4] as IntoIterator>::IntoIter;
650
651 fn into_iter(self) -> Self::IntoIter {
652 self.0.into_iter()
653 }
654}
655
656#[macro_export]
663macro_rules! word {
664 ($hex:expr) => {{
665 let word: Word = match $crate::word::Word::parse($hex) {
666 Ok(v) => v,
667 Err(e) => panic!("{}", e),
668 };
669
670 word
671 }};
672}