simplicity/
value.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! # Simplicity values
4//!
5//! Simplicity processes data in terms of [`Value`]s,
6//! i.e., inputs, intermediate results and outputs.
7
8use crate::dag::{Dag, DagLike};
9use crate::types::{CompleteBound, Final};
10use crate::BitIter;
11
12use crate::{BitCollector, EarlyEndOfStreamError};
13use core::{cmp, fmt, iter};
14use std::collections::VecDeque;
15use std::hash::Hash;
16use std::sync::Arc;
17
18/// A Simplicity value.
19#[derive(Clone)]
20pub struct Value {
21    /// The underlying data, in "padded" bit-encoded form, with the leftmost
22    /// bits encoded in the most-significant bits. So e.g. right(unit) is 0x80.
23    ///
24    /// We use the padded form, even though it is space-inefficient (sometimes
25    /// significantly so), for a couple reasons: first, this is the representation
26    /// used by the bit machine, so we want encoding/decoding to be as fast as
27    /// possible. Secondly, when destructuring a value (which we need to do during
28    /// scribing and pruning, at least) it is quite difficult to destructure a
29    /// compact-encoded product, since we would need to determine the compact
30    /// bitlengths of the children, and these quantities are not readily available.
31    inner: Arc<[u8]>,
32    /// An offset, in bits, at which the actual data starts. This is useful
33    /// because it allows constructing sub-values of a value without needing
34    /// to construct a new `inner` with all the bits offset.
35    bit_offset: usize,
36    /// The Simplicity type of the value.
37    ty: Arc<Final>,
38}
39
40/// Reference to a value, or to a sub-value of a value.
41#[derive(Debug, Clone)]
42pub struct ValueRef<'v> {
43    inner: &'v Arc<[u8]>,
44    bit_offset: usize,
45    ty: &'v Arc<Final>,
46}
47
48// Because two equal values may have different bit offsets, we must manually
49// implement the comparison traits. We do so by first comparing types, which
50// is constant overhead (this just compares TMRs). If those match, we know
51// the lengths and structures match, so we then compare the underlying byte
52// iterators.
53impl PartialEq for Value {
54    fn eq(&self, other: &Self) -> bool {
55        self.ty == other.ty && self.raw_byte_iter().eq(other.raw_byte_iter())
56    }
57}
58impl Eq for Value {}
59
60impl PartialOrd for Value {
61    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
62        Some(self.cmp(other))
63    }
64}
65impl Ord for Value {
66    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
67        self.ty
68            .cmp(&other.ty)
69            .then_with(|| self.raw_byte_iter().cmp(other.raw_byte_iter()))
70    }
71}
72
73impl core::hash::Hash for Value {
74    fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
75        b"Simplicity\x1fValue".hash(h);
76        self.ty.hash(h);
77        for val in self.raw_byte_iter() {
78            val.hash(h);
79        }
80    }
81}
82
83impl DagLike for ValueRef<'_> {
84    type Node = Self;
85
86    fn data(&self) -> &Self {
87        self
88    }
89
90    fn as_dag_node(&self) -> Dag<Self> {
91        if let Some((left, right)) = self.as_product() {
92            Dag::Binary(left, right)
93        } else if let Some(left) = self.as_left() {
94            Dag::Unary(left)
95        } else if let Some(right) = self.as_right() {
96            Dag::Unary(right)
97        } else {
98            assert!(self.ty.is_unit());
99            Dag::Nullary
100        }
101    }
102}
103
104impl ValueRef<'_> {
105    /// Check if the value is a unit.
106    pub fn is_unit(&self) -> bool {
107        self.ty.is_unit()
108    }
109
110    /// Helper function to read the first bit of a value
111    ///
112    /// If the first bit is not available (e.g. if the value has zero size)
113    /// then returns None.
114    fn first_bit(&self) -> Option<bool> {
115        let mask = if self.bit_offset % 8 == 0 {
116            0x80
117        } else {
118            1 << (7 - self.bit_offset % 8)
119        };
120        let res = self
121            .inner
122            .get(self.bit_offset / 8)
123            .map(|x| x & mask == mask);
124        res
125    }
126
127    /// Access the inner value of a left sum value.
128    pub fn as_left(&self) -> Option<Self> {
129        if self.first_bit() == Some(false) {
130            if let Some((lty, rty)) = self.ty.as_sum() {
131                let sum_width = 1 + cmp::max(lty.bit_width(), rty.bit_width());
132                Some(Self {
133                    inner: self.inner,
134                    bit_offset: self.bit_offset + sum_width - lty.bit_width(),
135                    ty: lty,
136                })
137            } else {
138                None
139            }
140        } else {
141            None
142        }
143    }
144
145    /// Access the inner value of a right sum value.
146    pub fn as_right(&self) -> Option<Self> {
147        if self.first_bit() == Some(true) {
148            if let Some((lty, rty)) = self.ty.as_sum() {
149                let sum_width = 1 + cmp::max(lty.bit_width(), rty.bit_width());
150                Some(Self {
151                    inner: self.inner,
152                    bit_offset: self.bit_offset + sum_width - rty.bit_width(),
153                    ty: rty,
154                })
155            } else {
156                None
157            }
158        } else {
159            None
160        }
161    }
162
163    /// Access the inner values of a product value.
164    pub fn as_product(&self) -> Option<(Self, Self)> {
165        if let Some((lty, rty)) = self.ty.as_product() {
166            Some((
167                Self {
168                    inner: self.inner,
169                    bit_offset: self.bit_offset,
170                    ty: lty,
171                },
172                Self {
173                    inner: self.inner,
174                    bit_offset: self.bit_offset + lty.bit_width(),
175                    ty: rty,
176                },
177            ))
178        } else {
179            None
180        }
181    }
182
183    /// Convert the reference back to a value.
184    pub fn to_value(&self) -> Value {
185        Value {
186            inner: Arc::clone(self.inner),
187            bit_offset: self.bit_offset,
188            ty: Arc::clone(self.ty),
189        }
190    }
191
192    /// Try to convert the value into a word.
193    pub fn to_word(&self) -> Option<Word> {
194        self.ty.as_word().map(|n| Word {
195            value: self.to_value(),
196            n,
197        })
198    }
199}
200
201pub struct RawByteIter<'v> {
202    value: &'v Value,
203    yielded_bytes: usize,
204}
205
206impl Iterator for RawByteIter<'_> {
207    type Item = u8;
208    fn next(&mut self) -> Option<Self::Item> {
209        if 8 * self.yielded_bytes >= self.value.ty.bit_width() {
210            None
211        } else if self.value.bit_offset % 8 == 0 {
212            self.yielded_bytes += 1;
213
214            Some(self.value.inner[self.value.bit_offset / 8 + self.yielded_bytes - 1])
215        } else {
216            self.yielded_bytes += 1;
217
218            let ret1 = self.value.inner[self.value.bit_offset / 8 + self.yielded_bytes - 1];
219            let ret2 = self
220                .value
221                .inner
222                .get(self.value.bit_offset / 8 + self.yielded_bytes)
223                .copied()
224                .unwrap_or(0);
225            let bit_offset = self.value.bit_offset % 8;
226            Some((ret1 << bit_offset) | (ret2 >> (8 - bit_offset)))
227        }
228    }
229}
230
231pub struct PreOrderIter<'v> {
232    inner: iter::Take<BitIter<RawByteIter<'v>>>,
233}
234
235impl Iterator for PreOrderIter<'_> {
236    type Item = bool;
237    fn next(&mut self) -> Option<Self::Item> {
238        self.inner.next()
239    }
240}
241
242/// Helper function to right-shift a value by one bit.
243///
244/// This is used for putting a value into a sum type. It takes the value's
245/// bit encoding and current bit offset, and returns a new bit-encoding with
246/// a new bit inserted upfront and a new bit offset.
247fn right_shift_1(inner: &Arc<[u8]>, bit_offset: usize, new_bit: bool) -> (Arc<[u8]>, usize) {
248    // If the current bit offset is nonzero this is super easy: we just
249    // lower the bit offset and call that a fix.
250    if bit_offset > 0 {
251        if new_bit {
252            let new_bit_offset = bit_offset - 1;
253            let mut bx: Box<[u8]> = inner.as_ref().into();
254            bx[new_bit_offset / 8] |= 1 << (7 - new_bit_offset % 8);
255            (bx.into(), new_bit_offset)
256        } else {
257            // ...and if we are inserting a 0 we don't even need to allocate a new [u8]
258            (Arc::clone(inner), bit_offset - 1)
259        }
260    } else {
261        // If the current bit offset is 0, we just shift everything right by 8
262        // and then do pretty-much the same thing as above. This sometimes will
263        // waste 7 bits, but it avoids needing to iterate through all of `inner`.
264        let mut new = Vec::with_capacity(inner.len() + 1);
265        new.push(u8::from(new_bit));
266        new.extend(inner.iter().copied());
267        (new.into(), 7)
268    }
269}
270
271/// Helper function to copy `nbits` bits from `src`, starting at bit-offset `src_offset`,
272/// into `dst`, starting at bit-offset `dst_offset`.
273///
274/// Thanks ChatGPT for suggesting we extract this function.
275fn copy_bits(src: &[u8], src_offset: usize, dst: &mut [u8], dst_offset: usize, nbits: usize) {
276    // For each bit i in 0..nbits, extract the bit from `src`
277    // and insert it into `dst`.
278    for i in 0..nbits {
279        let bit = (src[(src_offset + i) / 8] >> (7 - (src_offset + i) % 8)) & 1;
280        dst[(dst_offset + i) / 8] |= bit << (7 - (dst_offset + i) % 8);
281    }
282}
283
284/// Helper function to take the product of two values (i.e. their concatenation).
285///
286/// If either `left_inner` or `right_inner` is not provided, it is assumed to be
287/// padding and will be stored as all zeros.
288///
289/// Returns the new bit data and the offset (NOT the length) of the data.
290fn product(
291    left: Option<(&Arc<[u8]>, usize)>,
292    left_bit_length: usize,
293    right: Option<(&Arc<[u8]>, usize)>,
294    right_bit_length: usize,
295) -> (Arc<[u8]>, usize) {
296    if left_bit_length == 0 {
297        if let Some((right, right_bit_offset)) = right {
298            (Arc::clone(right), right_bit_offset)
299        } else if right_bit_length == 0 {
300            (Arc::new([]), 0)
301        } else {
302            (Arc::from(vec![0; right_bit_length.div_ceil(8)]), 0)
303        }
304    } else if right_bit_length == 0 {
305        if let Some((lt, left_bit_offset)) = left {
306            (Arc::clone(lt), left_bit_offset)
307        } else {
308            (Arc::from(vec![0; left_bit_length.div_ceil(8)]), 0)
309        }
310    } else {
311        // Both left and right have nonzero lengths. This is the only "real" case
312        // in which we have to do something beyond cloning Arcs or allocating
313        // zeroed vectors. In this case we left-shift both as much as possible.
314        let mut bx = Box::<[u8]>::from(vec![0; (left_bit_length + right_bit_length).div_ceil(8)]);
315        if let Some((left, left_bit_offset)) = left {
316            copy_bits(left, left_bit_offset, &mut bx, 0, left_bit_length);
317        }
318        if let Some((right, right_bit_offset)) = right {
319            copy_bits(
320                right,
321                right_bit_offset,
322                &mut bx,
323                left_bit_length,
324                right_bit_length,
325            );
326        }
327
328        (bx.into(), 0)
329    }
330}
331
332impl Value {
333    /// Make a cheap copy of the value.
334    pub fn shallow_clone(&self) -> Self {
335        Self {
336            inner: Arc::clone(&self.inner),
337            bit_offset: self.bit_offset,
338            ty: Arc::clone(&self.ty),
339        }
340    }
341
342    /// Access the type of the value.
343    pub fn ty(&self) -> &Final {
344        &self.ty
345    }
346
347    /// Create the unit value.
348    pub fn unit() -> Self {
349        Self {
350            inner: Arc::new([]),
351            bit_offset: 0,
352            ty: Final::unit(),
353        }
354    }
355
356    /// Create a left value that wraps the given `inner` value.
357    pub fn left(inner: Self, right: Arc<Final>) -> Self {
358        let total_width = cmp::max(inner.ty.bit_width(), right.bit_width());
359
360        let (concat, concat_offset) = product(
361            None,
362            total_width - inner.ty.bit_width(),
363            Some((&inner.inner, inner.bit_offset)),
364            inner.ty.bit_width(),
365        );
366        let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, false);
367        Self {
368            inner: new_inner,
369            bit_offset: new_bit_offset,
370            ty: Final::sum(Arc::clone(&inner.ty), right),
371        }
372    }
373
374    /// Create a right value that wraps the given `inner` value.
375    pub fn right(left: Arc<Final>, inner: Self) -> Self {
376        let total_width = cmp::max(left.bit_width(), inner.ty.bit_width());
377        let (concat, concat_offset) = product(
378            None,
379            total_width - inner.ty.bit_width(),
380            Some((&inner.inner, inner.bit_offset)),
381            inner.ty.bit_width(),
382        );
383        let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, true);
384        Self {
385            inner: new_inner,
386            bit_offset: new_bit_offset,
387            ty: Final::sum(left, Arc::clone(&inner.ty)),
388        }
389    }
390
391    /// Create a product value that wraps the given `left` and `right` values.
392    pub fn product(left: Self, right: Self) -> Self {
393        let (new_inner, new_bit_offset) = product(
394            Some((&left.inner, left.bit_offset)),
395            left.ty.bit_width(),
396            Some((&right.inner, right.bit_offset)),
397            right.ty.bit_width(),
398        );
399        Self {
400            inner: new_inner,
401            bit_offset: new_bit_offset,
402            ty: Final::product(Arc::clone(&left.ty), Arc::clone(&right.ty)),
403        }
404    }
405
406    /// Create a none value.
407    pub fn none(right: Arc<Final>) -> Self {
408        Self::left(Value::unit(), right)
409    }
410
411    /// Create a some value.
412    pub fn some(inner: Self) -> Self {
413        Self::right(Final::unit(), inner)
414    }
415
416    /// Return the bit length of the value in compact encoding.
417    pub fn compact_len(&self) -> usize {
418        self.iter_compact().count()
419    }
420
421    /// Return the bit length of the value in padded encoding.
422    pub fn padded_len(&self) -> usize {
423        self.ty.bit_width()
424    }
425
426    /// Check if the value is a nested product of units.
427    /// In this case, the value contains no information.
428    pub fn is_empty(&self) -> bool {
429        self.ty.bit_width() == 0
430    }
431
432    /// Check if the value is a unit.
433    pub fn is_unit(&self) -> bool {
434        self.ty.is_unit()
435    }
436
437    /// A reference to this value, which can be recursed over.
438    pub fn as_ref(&self) -> ValueRef<'_> {
439        ValueRef {
440            inner: &self.inner,
441            bit_offset: self.bit_offset,
442            ty: &self.ty,
443        }
444    }
445
446    /// Access the inner value of a left sum value.
447    pub fn as_left(&self) -> Option<ValueRef<'_>> {
448        self.as_ref().as_left()
449    }
450
451    /// Access the inner value of a right sum value.
452    pub fn as_right(&self) -> Option<ValueRef<'_>> {
453        self.as_ref().as_right()
454    }
455
456    /// Access the inner values of a product value.
457    pub fn as_product(&self) -> Option<(ValueRef<'_>, ValueRef<'_>)> {
458        self.as_ref().as_product()
459    }
460
461    /// Create a 1-bit integer.
462    ///
463    /// ## Panics
464    ///
465    /// The value is out of range.
466    pub fn u1(value: u8) -> Self {
467        assert!(value <= 1, "{} out of range for Value::u1", value);
468        Self {
469            inner: Arc::new([value]),
470            bit_offset: 7,
471            ty: Final::two_two_n(0),
472        }
473    }
474
475    /// Create a 2-bit integer.
476    ///
477    /// ## Panics
478    ///
479    /// The value is out of range.
480    pub fn u2(value: u8) -> Self {
481        assert!(value <= 3, "{} out of range for Value::u2", value);
482        Self {
483            inner: Arc::new([value]),
484            bit_offset: 6,
485            ty: Final::two_two_n(1),
486        }
487    }
488
489    /// Create a 4-bit integer.
490    ///
491    /// ## Panics
492    ///
493    /// The value is ouf of range.
494    pub fn u4(value: u8) -> Self {
495        assert!(value <= 15, "{} out of range for Value::u2", value);
496        Self {
497            inner: Arc::new([value]),
498            bit_offset: 4,
499            ty: Final::two_two_n(2),
500        }
501    }
502
503    /// Create an 8-bit integer.
504    pub fn u8(value: u8) -> Self {
505        Self {
506            inner: Arc::new([value]),
507            bit_offset: 0,
508            ty: Final::two_two_n(3),
509        }
510    }
511
512    /// Create a 16-bit integer.
513    pub fn u16(bytes: u16) -> Self {
514        Self {
515            inner: Arc::new(bytes.to_be_bytes()),
516            bit_offset: 0,
517            ty: Final::two_two_n(4),
518        }
519    }
520
521    /// Create a 32-bit integer.
522    pub fn u32(bytes: u32) -> Self {
523        Self {
524            inner: Arc::new(bytes.to_be_bytes()),
525            bit_offset: 0,
526            ty: Final::two_two_n(5),
527        }
528    }
529
530    /// Create a 64-bit integer.
531    pub fn u64(bytes: u64) -> Self {
532        Self {
533            inner: Arc::new(bytes.to_be_bytes()),
534            bit_offset: 0,
535            ty: Final::two_two_n(6),
536        }
537    }
538
539    /// Create a 128-bit integer.
540    pub fn u128(bytes: u128) -> Self {
541        Self {
542            inner: Arc::new(bytes.to_be_bytes()),
543            bit_offset: 0,
544            ty: Final::two_two_n(7),
545        }
546    }
547
548    /// Create a 256-bit integer.
549    pub fn u256(bytes: [u8; 32]) -> Self {
550        Self {
551            inner: Arc::new(bytes),
552            bit_offset: 0,
553            ty: Final::two_two_n(8),
554        }
555    }
556
557    /// Create a 512-bit integer.
558    pub fn u512(bytes: [u8; 64]) -> Self {
559        Self {
560            inner: Arc::new(bytes),
561            bit_offset: 0,
562            ty: Final::two_two_n(9),
563        }
564    }
565
566    /// Create a value from a byte array.
567    ///
568    /// ## Panics
569    ///
570    /// The array length is not a power of two.
571    pub fn from_byte_array<const N: usize>(bytes: [u8; N]) -> Self {
572        assert!(N.is_power_of_two(), "Array length must be a power of two");
573        let mut values: VecDeque<_> = bytes.into_iter().map(Value::u8).collect();
574
575        while values.len() > 1 {
576            let mut alt_values = VecDeque::with_capacity(values.len() / 2);
577
578            while let (Some(left), Some(right)) = (values.pop_front(), values.pop_front()) {
579                alt_values.push_back(Value::product(left, right));
580            }
581
582            values = alt_values;
583        }
584
585        values.into_iter().next().unwrap()
586    }
587
588    /// Yields an iterator over the "raw bytes" of the value.
589    ///
590    /// The returned bytes match the padded bit-encoding of the value. You
591    /// may wish to call [`Self::iter_padded`] instead to obtain the bits,
592    /// but this method is more efficient in some contexts.
593    pub fn raw_byte_iter(&self) -> RawByteIter<'_> {
594        RawByteIter {
595            value: self,
596            yielded_bytes: 0,
597        }
598    }
599
600    /// Return an iterator over the compact bit encoding of the value.
601    ///
602    /// This encoding is used for writing witness data and for computing IHRs.
603    pub fn iter_compact(&self) -> CompactBitsIter<'_> {
604        CompactBitsIter::new(self.as_ref())
605    }
606
607    /// Return an iterator over the padded bit encoding of the value.
608    ///
609    /// This encoding is used to represent the value in the Bit Machine.
610    pub fn iter_padded(&self) -> PreOrderIter<'_> {
611        PreOrderIter {
612            inner: BitIter::new(self.raw_byte_iter()).take(self.ty.bit_width()),
613        }
614    }
615
616    /// Check if the value is of the given type.
617    pub fn is_of_type(&self, ty: &Final) -> bool {
618        self.ty.as_ref() == ty
619    }
620
621    /// Get the zero value for the given type.
622    ///
623    /// The zero value serializes to a string of zeroes.
624    ///
625    /// ## Construction
626    ///
627    /// - `zero( 1 )` = `()`
628    /// - `zero( A + B )` = `zero(A)`
629    /// - `zero( A × B )` = `zero(A) × zero(B)`
630    pub fn zero(ty: &Final) -> Self {
631        Self {
632            inner: Arc::from(vec![0; ty.bit_width().div_ceil(8)]),
633            bit_offset: 0,
634            ty: Arc::new(ty.clone()),
635        }
636    }
637
638    /// Try to convert the value into a word.
639    ///
640    /// The value is cheaply cloned.
641    pub fn to_word(&self) -> Option<Word> {
642        self.ty.as_word().map(|n| Word {
643            value: self.shallow_clone(),
644            n,
645        })
646    }
647
648    /// Prune the value down to the given type.
649    ///
650    /// The pruned type must be _smaller than or equal to_ the current type of the value.
651    /// Otherwise, this method returns `None`.
652    ///
653    /// ## Smallness
654    ///
655    /// - `T` ≤ `T` for all types `T`
656    /// - `1` ≤ `T` for all types `T`
657    /// - `A1 + B1` ≤ `A2 + B2` if `A1` ≤ `A2` and `B1` ≤ `B2`
658    /// - `A1 × B1` ≤ `A2 × B2` if `A1` ≤ `A2` and `B1` ≤ `B2`
659    ///
660    /// ## Pruning
661    ///
662    /// - `prune( v: T, 1 )` = `(): 1`
663    /// - `prune( L(l): A1 + B1, A2 + B2 )` = `prune(l: A1, A2) : A2 + B2`
664    /// - `prune( R(r): A1 + B1, A2 + B2 )` = `prune(r: B1, B2) : A2 + B2`
665    /// - `prune( (l, r): A1 × B1, A2 × B2 )` = `( prune(l: A1, A2), prune(r: B1, B2): A2 × B2`
666    pub fn prune(&self, pruned_ty: &Final) -> Option<Self> {
667        enum Task<'v, 'ty> {
668            Prune(ValueRef<'v>, &'ty Final),
669            MakeLeft(Arc<Final>),
670            MakeRight(Arc<Final>),
671            MakeProduct,
672        }
673
674        let mut stack = vec![Task::Prune(self.as_ref(), pruned_ty)];
675        let mut output = vec![];
676
677        while let Some(task) = stack.pop() {
678            match task {
679                Task::Prune(value, pruned_ty) if value.ty.as_ref() == pruned_ty => {
680                    output.push(value.to_value())
681                }
682                Task::Prune(value, pruned_ty) => match pruned_ty.bound() {
683                    CompleteBound::Unit => output.push(Value::unit()),
684                    CompleteBound::Sum(l_ty, r_ty) => {
685                        if let Some(l_value) = value.as_left() {
686                            stack.push(Task::MakeLeft(Arc::clone(r_ty)));
687                            stack.push(Task::Prune(l_value, l_ty));
688                        } else {
689                            let r_value = value.as_right()?;
690                            stack.push(Task::MakeRight(Arc::clone(l_ty)));
691                            stack.push(Task::Prune(r_value, r_ty));
692                        }
693                    }
694                    CompleteBound::Product(l_ty, r_ty) => {
695                        let (l_value, r_value) = value.as_product()?;
696                        stack.push(Task::MakeProduct);
697                        stack.push(Task::Prune(r_value, r_ty));
698                        stack.push(Task::Prune(l_value, l_ty));
699                    }
700                },
701                Task::MakeLeft(r_ty) => {
702                    let l_value = output.pop().unwrap();
703                    output.push(Value::left(l_value, r_ty));
704                }
705                Task::MakeRight(l_ty) => {
706                    let r_value = output.pop().unwrap();
707                    output.push(Value::right(l_ty, r_value));
708                }
709                Task::MakeProduct => {
710                    let r_value = output.pop().unwrap();
711                    let l_value = output.pop().unwrap();
712                    output.push(Value::product(l_value, r_value));
713                }
714            }
715        }
716
717        debug_assert_eq!(output.len(), 1);
718        output.pop()
719    }
720}
721
722impl fmt::Debug for Value {
723    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
724        f.debug_struct("Value")
725            .field("value", &format_args!("{}", self))
726            .field("ty", &self.ty)
727            .field("raw_value", &self.inner)
728            .field("raw_bit_offset", &self.bit_offset)
729            .finish()
730    }
731}
732
733impl fmt::Display for Value {
734    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
735        // This is a copy of the logic inside `CompactBitsIter` except
736        // that we handle products more explicitly.
737        enum S<'v> {
738            Disp(ValueRef<'v>),
739            DispUnlessUnit(ValueRef<'v>),
740            DispCh(char),
741        }
742
743        let mut stack = Vec::with_capacity(1024);
744        // Next node to visit, and a boolean indicating whether we should
745        // display units explicitly (turned off for sums, since a sum of
746        // a unit is displayed simply as 0 or 1.
747        stack.push(S::Disp(self.as_ref()));
748
749        while let Some(next) = stack.pop() {
750            let value = match next {
751                S::Disp(ref value) | S::DispUnlessUnit(ref value) => value,
752                S::DispCh(ch) => {
753                    write!(f, "{}", ch)?;
754                    continue;
755                }
756            };
757
758            if value.is_unit() {
759                if !matches!(next, S::DispUnlessUnit(..)) {
760                    f.write_str("ε")?;
761                }
762            } else if let Some(l_value) = value.as_left() {
763                f.write_str("0")?;
764                stack.push(S::DispUnlessUnit(l_value));
765            } else if let Some(r_value) = value.as_right() {
766                f.write_str("1")?;
767                stack.push(S::DispUnlessUnit(r_value));
768            } else if let Some((l_value, r_value)) = value.as_product() {
769                stack.push(S::DispCh(')'));
770                stack.push(S::Disp(r_value));
771                stack.push(S::DispCh(','));
772                stack.push(S::Disp(l_value));
773                stack.push(S::DispCh('('));
774            } else {
775                unreachable!()
776            }
777        }
778        Ok(())
779    }
780}
781
782/// An iterator over the bits of the compact encoding of a [`Value`].
783#[derive(Debug, Clone)]
784pub struct CompactBitsIter<'v> {
785    stack: Vec<ValueRef<'v>>,
786}
787
788impl<'v> CompactBitsIter<'v> {
789    /// Create an iterator over the bits of the compact encoding of the `value`.
790    fn new(value: ValueRef<'v>) -> Self {
791        Self { stack: vec![value] }
792    }
793}
794
795impl Iterator for CompactBitsIter<'_> {
796    type Item = bool;
797
798    fn next(&mut self) -> Option<Self::Item> {
799        while let Some(value) = self.stack.pop() {
800            if value.ty.bit_width() == 0 {
801                // NOP
802            } else if let Some(l_value) = value.as_left() {
803                self.stack.push(l_value);
804                return Some(false);
805            } else if let Some(r_value) = value.as_right() {
806                self.stack.push(r_value);
807                return Some(true);
808            } else if let Some((l_value, r_value)) = value.as_product() {
809                self.stack.push(r_value);
810                self.stack.push(l_value);
811            }
812        }
813
814        None
815    }
816}
817
818impl Value {
819    /// Decode a value of the given type from its compact bit encoding.
820    pub fn from_compact_bits<I: Iterator<Item = u8>>(
821        bits: &mut BitIter<I>,
822        ty: &Final,
823    ) -> Result<Self, EarlyEndOfStreamError> {
824        enum State<'a> {
825            ProcessType(&'a Final),
826            DoSumL(Arc<Final>),
827            DoSumR(Arc<Final>),
828            DoProduct,
829        }
830
831        let mut stack = vec![State::ProcessType(ty)];
832        let mut result_stack = vec![];
833        while let Some(state) = stack.pop() {
834            match state {
835                State::ProcessType(ty) if ty.has_padding() => match ty.bound() {
836                    CompleteBound::Unit => result_stack.push(Value::unit()),
837                    CompleteBound::Sum(ref l, ref r) => {
838                        if !bits.next().ok_or(EarlyEndOfStreamError)? {
839                            stack.push(State::DoSumL(Arc::clone(r)));
840                            stack.push(State::ProcessType(l));
841                        } else {
842                            stack.push(State::DoSumR(Arc::clone(l)));
843                            stack.push(State::ProcessType(r));
844                        }
845                    }
846                    CompleteBound::Product(ref l, ref r) => {
847                        stack.push(State::DoProduct);
848                        stack.push(State::ProcessType(r));
849                        stack.push(State::ProcessType(l));
850                    }
851                },
852                State::ProcessType(ty) => {
853                    // no padding no problem
854                    result_stack.push(Value::from_padded_bits(bits, ty)?);
855                }
856                State::DoSumL(r) => {
857                    let val = result_stack.pop().unwrap();
858                    result_stack.push(Value::left(val, r));
859                }
860                State::DoSumR(l) => {
861                    let val = result_stack.pop().unwrap();
862                    result_stack.push(Value::right(l, val));
863                }
864                State::DoProduct => {
865                    let val_r = result_stack.pop().unwrap();
866                    let val_l = result_stack.pop().unwrap();
867                    result_stack.push(Value::product(val_l, val_r));
868                }
869            }
870        }
871        debug_assert_eq!(result_stack.len(), 1);
872        Ok(result_stack.pop().unwrap())
873    }
874
875    /// Decode a value of the given type from its padded bit encoding.
876    pub fn from_padded_bits<I: Iterator<Item = u8>>(
877        bits: &mut BitIter<I>,
878        ty: &Final,
879    ) -> Result<Self, EarlyEndOfStreamError> {
880        const MAX_INITIAL_ALLOC: usize = 32 * 1024 * 1024; // 4 megabytes
881
882        let cap = cmp::min(MAX_INITIAL_ALLOC, ty.bit_width().div_ceil(8));
883        let mut blob = Vec::with_capacity(cap);
884        for _ in 0..ty.bit_width() / 8 {
885            blob.push(bits.read_u8()?);
886        }
887        let mut last = 0u8;
888        for i in 0..ty.bit_width() % 8 {
889            if bits.read_bit()? {
890                last |= 1 << (7 - i);
891            }
892        }
893        blob.push(last);
894
895        Ok(Value {
896            inner: blob.into(),
897            bit_offset: 0,
898            ty: Arc::new(ty.clone()),
899        })
900    }
901}
902
903/// A Simplicity word. A value of type `TWO^(2^n)` for some `0 ≤ n < 32`.
904#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
905pub struct Word {
906    /// Value of type `TWO^(2^n)`.
907    value: Value,
908    /// 0 ≤ n < 32.
909    n: u32,
910}
911
912macro_rules! construct_word_fallible {
913    ($name: ident, $n: expr, $text: expr) => {
914        #[doc = "Create"]
915        #[doc = $text]
916        #[doc = "word.\n\n"]
917        #[doc = "## Panics\n"]
918        #[doc = "The value is ouf of range."]
919        pub fn $name(bit: u8) -> Self {
920            Self {
921                value: Value::$name(bit),
922                n: $n,
923            }
924        }
925    };
926}
927
928macro_rules! construct_word {
929    ($name: ident, $ty: ty, $n: expr, $text: expr) => {
930        #[doc = "Create"]
931        #[doc = $text]
932        #[doc = "word."]
933        pub fn $name(bit: $ty) -> Self {
934            Self {
935                value: Value::$name(bit),
936                n: $n,
937            }
938        }
939    };
940}
941
942impl Word {
943    /// Concatenate two words into a larger word.
944    ///
945    /// Both words have to have the same length, which is 2^n bits.
946    /// The resulting word will be 2^(n + 1) bits long.
947    ///
948    /// Returns `None` if the words differ in length.
949    ///
950    /// Returns `None` if the words are already 2^31 bits long
951    /// _(the resulting word would be longer than 2^31 bits, which is not supported)_.
952    pub fn product(self, right: Self) -> Option<Self> {
953        if self.n == right.n && self.n < 30 {
954            Some(Self {
955                value: Value::product(self.value, right.value),
956                n: self.n + 1,
957            })
958        } else {
959            None
960        }
961    }
962
963    construct_word_fallible!(u1, 0, "a 1-bit");
964    construct_word_fallible!(u2, 1, "a 2-bit");
965    construct_word_fallible!(u4, 2, "a 4-bit");
966    construct_word!(u8, u8, 3, "an 8-bit");
967    construct_word!(u16, u16, 4, "a 16-bit");
968    construct_word!(u32, u32, 5, "a 32-bit");
969    construct_word!(u64, u64, 6, "a 64-bit");
970    construct_word!(u128, u128, 7, "a 128-bit");
971    construct_word!(u256, [u8; 32], 8, "a 256-bit");
972    construct_word!(u512, [u8; 64], 9, "a 512-bit");
973
974    /// Make a cheap copy of the word.
975    pub fn shallow_clone(&self) -> Self {
976        Self {
977            value: self.value.shallow_clone(),
978            n: self.n,
979        }
980    }
981
982    /// Access the value of the word.
983    pub fn as_value(&self) -> &Value {
984        &self.value
985    }
986
987    /// The word is of type `TWO^(2^n)`. Return `n`.
988    pub fn n(&self) -> u32 {
989        self.n
990    }
991
992    /// Return the bit length of the word.
993    ///
994    /// The word is of type `TWO^(2^n)`. Return `2^n`.
995    #[allow(clippy::len_without_is_empty)]
996    pub fn len(&self) -> usize {
997        2usize.pow(self.n)
998    }
999
1000    /// Return an iterator over the bit encoding of the word.
1001    ///
1002    /// Words have no padding, so their compact encoding is the same as the padded encoding.
1003    /// The universal encoding can be used in all situations.
1004    pub fn iter(&self) -> impl Iterator<Item = bool> + '_ {
1005        self.value.iter_compact()
1006    }
1007
1008    /// Decode a word of type `TWO^(2^n)` from bits.
1009    ///
1010    /// ## Panics
1011    ///
1012    /// n is greater than 31.
1013    pub fn from_bits<I: Iterator<Item = u8>>(
1014        bits: &mut BitIter<I>,
1015        n: u32,
1016    ) -> Result<Self, EarlyEndOfStreamError> {
1017        assert!(n < 32, "TWO^(2^{n}) is not supported as a word type");
1018        let ty = Final::two_two_n(n as usize); // cast safety: 32-bit machine or higher
1019        let value = Value::from_compact_bits(bits, &ty)?;
1020        Ok(Self { value, n })
1021    }
1022}
1023
1024impl fmt::Debug for Word {
1025    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1026        fmt::Display::fmt(self, f)
1027    }
1028}
1029
1030impl fmt::Display for Word {
1031    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1032        use hex::DisplayHex;
1033
1034        if let Ok(hex) = self.iter().try_collect_bytes() {
1035            write!(f, "0x{}", hex.as_hex())
1036        } else {
1037            f.write_str("0b")?;
1038            for bit in self.iter() {
1039                match bit {
1040                    false => f.write_str("0")?,
1041                    true => f.write_str("1")?,
1042                }
1043            }
1044            Ok(())
1045        }
1046    }
1047}
1048
1049#[cfg(test)]
1050mod tests {
1051    use super::*;
1052    use crate::bit_encoding::{BitCollector as _, BitIter};
1053    use crate::jet::type_name::TypeName;
1054
1055    #[test]
1056    fn value_len() {
1057        let v = Value::u4(6);
1058        let s_v = Value::some(v.shallow_clone());
1059        let n_v = Value::none(Final::two_two_n(2));
1060
1061        assert_eq!(v.compact_len(), 4);
1062        assert_eq!(v.padded_len(), 4);
1063        assert_eq!(s_v.compact_len(), 5);
1064        assert_eq!(s_v.padded_len(), 5);
1065        assert_eq!(n_v.compact_len(), 1);
1066        assert_eq!(n_v.padded_len(), 5);
1067    }
1068
1069    #[test]
1070    fn value_display() {
1071        // Only test a couple values becasue we probably want to change this
1072        // at some point and will have to redo this test.
1073        assert_eq!(Value::u1(0).to_string(), "0",);
1074        assert_eq!(Value::u1(1).to_string(), "1",);
1075        assert_eq!(Value::u4(6).to_string(), "((0,1),(1,0))",);
1076    }
1077
1078    #[test]
1079    fn is_of_type() {
1080        let value_typename = [
1081            (Value::unit(), TypeName(b"1")),
1082            (Value::left(Value::unit(), Final::unit()), TypeName(b"+11")),
1083            (Value::right(Final::unit(), Value::unit()), TypeName(b"+11")),
1084            (
1085                Value::left(Value::unit(), Final::two_two_n(8)),
1086                TypeName(b"+1h"),
1087            ),
1088            (
1089                Value::right(Final::two_two_n(8), Value::unit()),
1090                TypeName(b"+h1"),
1091            ),
1092            (
1093                Value::product(Value::unit(), Value::unit()),
1094                TypeName(b"*11"),
1095            ),
1096            (Value::u8(u8::MAX), TypeName(b"c")),
1097            (Value::u64(u64::MAX), TypeName(b"l")),
1098        ];
1099
1100        for (value, typename) in value_typename {
1101            let ty = typename.to_final();
1102            assert!(value.is_of_type(ty.as_ref()));
1103        }
1104    }
1105
1106    #[test]
1107    fn prune_regression_1() {
1108        // Found this when fuzzing Elements; unsure how to reduce it further.
1109        let nontrivial_sum = Value::product(
1110            Value::right(Final::two_two_n(4), Value::u16(0)),
1111            Value::u8(0),
1112        );
1113        // Formatting should succeed and have no effect.
1114        let _ = format!("{nontrivial_sum}");
1115        // Pruning should succeed and have no effect.
1116        assert_eq!(
1117            nontrivial_sum.prune(nontrivial_sum.ty()),
1118            Some(nontrivial_sum)
1119        );
1120    }
1121
1122    #[test]
1123    fn prune() {
1124        let test_vectors = [
1125            (Value::unit(), Value::unit()),
1126            (Value::u64(42), Value::unit()),
1127            (
1128                Value::left(Value::u64(42), Final::u64()),
1129                Value::left(Value::u64(42), Final::unit()),
1130            ),
1131            (
1132                Value::right(Final::u64(), Value::u64(1337)),
1133                Value::right(Final::unit(), Value::u64(1337)),
1134            ),
1135            (
1136                Value::product(Value::u64(42), Value::u64(1337)),
1137                Value::product(Value::u64(42), Value::unit()),
1138            ),
1139            (
1140                Value::product(Value::u64(42), Value::u64(1337)),
1141                Value::product(Value::unit(), Value::u64(1337)),
1142            ),
1143        ];
1144
1145        for (value, expected_pruned_value) in test_vectors {
1146            assert_eq!(
1147                value.prune(expected_pruned_value.ty()),
1148                Some(expected_pruned_value)
1149            );
1150        }
1151
1152        let bad_test_vectors = [
1153            (Value::unit(), Final::u1()),
1154            (
1155                Value::product(Value::unit(), Value::unit()),
1156                Final::sum(Final::unit(), Final::unit()),
1157            ),
1158            (
1159                Value::left(Value::unit(), Final::unit()),
1160                Final::product(Final::unit(), Final::unit()),
1161            ),
1162            (
1163                Value::right(Final::unit(), Value::unit()),
1164                Final::product(Final::unit(), Final::unit()),
1165            ),
1166        ];
1167
1168        for (value, pruned_ty) in bad_test_vectors {
1169            assert_eq!(value.prune(&pruned_ty), None);
1170        }
1171    }
1172
1173    #[test]
1174    fn zero_value() {
1175        let test_vectors = [
1176            (Final::unit(), Value::unit()),
1177            (Final::u8(), Value::u8(0)),
1178            (Final::u64(), Value::u64(0)),
1179            (
1180                Final::product(Final::u16(), Final::u32()),
1181                Value::product(Value::u16(0), Value::u32(0)),
1182            ),
1183            (
1184                Final::sum(Final::unit(), Final::u64()),
1185                Value::left(Value::unit(), Final::u64()),
1186            ),
1187            (
1188                Final::product(Final::unit(), Final::unit()),
1189                Value::product(Value::unit(), Value::unit()),
1190            ),
1191        ];
1192
1193        for (ty, expected_default_value) in test_vectors {
1194            assert_eq!(Value::zero(&ty), expected_default_value);
1195        }
1196    }
1197
1198    #[test]
1199    fn compact_round_trip() {
1200        let v = Value::u64(0xff00_00ff_ff00_00ff);
1201        let (bits, _) = v.iter_compact().collect_bits();
1202        let mut iter = BitIter::new(bits.into_iter());
1203        let new_v = Value::from_compact_bits(&mut iter, &v.ty).unwrap();
1204        assert_eq!(v, new_v);
1205    }
1206
1207    #[test]
1208    fn padded_round_trip() {
1209        let v = Value::u64(0xff00_00ff_ff00_00ff);
1210        let (bits, _) = v.iter_padded().collect_bits();
1211        let mut iter = BitIter::new(bits.into_iter());
1212        let new_v = Value::from_padded_bits(&mut iter, &v.ty).unwrap();
1213        assert_eq!(v, new_v);
1214    }
1215}
1216
1217#[cfg(bench)]
1218mod benches {
1219    use super::*;
1220
1221    use crate::bit_encoding::{BitCollector as _, BitIter};
1222
1223    use test::{black_box, Bencher};
1224
1225    // Create values directly
1226    #[bench]
1227    fn bench_value_create_u64(bh: &mut Bencher) {
1228        bh.iter(|| black_box(Value::u64(0xff00_00ff_ff00_00ff)))
1229    }
1230
1231    #[bench]
1232    fn bench_value_create_u2048(bh: &mut Bencher) {
1233        bh.iter(|| black_box(Value::from_byte_array([0xcd; 2048])));
1234    }
1235
1236    #[bench]
1237    fn bench_value_create_deep_some(bh: &mut Bencher) {
1238        bh.iter(|| {
1239            let mut kilo = Value::from_byte_array([0xab; 1024]);
1240            for _ in 0..1000 {
1241                kilo = Value::some(kilo.shallow_clone());
1242            }
1243            black_box(kilo)
1244        });
1245    }
1246
1247    #[bench]
1248    fn bench_value_create_64k(bh: &mut Bencher) {
1249        bh.iter(|| {
1250            let mut kilo = Value::from_byte_array([0xab; 1024]);
1251            for _ in 0..5 {
1252                kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1253            }
1254            black_box(kilo)
1255        });
1256    }
1257
1258    #[bench]
1259    fn bench_value_create_512_256(bh: &mut Bencher) {
1260        bh.iter(|| {
1261            // This is a common "slow" pattern in my Elements fuzzer; it is a deeply
1262            // nested product of 2^512 x 2^256, which is not a "primitive numeric
1263            // type" and therefore cannot be quickly decoded from compact bits by
1264            // simply matching to pre-computed types.
1265            //
1266            // However, this type is a giant product of bits. Its compact encoding
1267            // is therefore equal to its padded encoding and we should be able to
1268            // quickly decode it.
1269            let mut s512_256 = Value::product(
1270                Value::from_byte_array([0x12; 64]),
1271                Value::from_byte_array([0x23; 32]),
1272            );
1273            for _ in 0..5 {
1274                s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1275            }
1276            black_box(s512_256);
1277        });
1278    }
1279
1280    // Create values from padded bits
1281    fn padded_bits(v: &Value) -> (Vec<u8>, &Final) {
1282        let (bits, _) = v.iter_padded().collect_bits();
1283        (bits, v.ty.as_ref())
1284    }
1285
1286    #[bench]
1287    fn bench_value_create_u64_padded(bh: &mut Bencher) {
1288        let v = Value::u64(0xff00_00ff_ff00_00ff);
1289        let (bits, ty) = padded_bits(&v);
1290        bh.iter(|| {
1291            black_box(Value::from_padded_bits(
1292                &mut BitIter::new(bits.iter().copied()),
1293                ty,
1294            ))
1295        })
1296    }
1297
1298    #[bench]
1299    fn bench_value_create_u2048_padded(bh: &mut Bencher) {
1300        let v = Value::from_byte_array([0xcd; 2048]);
1301        let (bits, ty) = padded_bits(&v);
1302        bh.iter(|| {
1303            black_box(Value::from_padded_bits(
1304                &mut BitIter::new(bits.iter().copied()),
1305                ty,
1306            ))
1307        })
1308    }
1309
1310    #[bench]
1311    fn bench_value_create_deep_some_padded(bh: &mut Bencher) {
1312        let mut kilo = Value::from_byte_array([0xab; 1024]);
1313        for _ in 0..1000 {
1314            kilo = Value::some(kilo.shallow_clone());
1315        }
1316        let (bits, ty) = padded_bits(&kilo);
1317        bh.iter(|| {
1318            black_box(Value::from_padded_bits(
1319                &mut BitIter::new(bits.iter().copied()),
1320                ty,
1321            ))
1322        })
1323    }
1324
1325    #[bench]
1326    fn bench_value_create_64k_padded(bh: &mut Bencher) {
1327        let mut kilo = Value::from_byte_array([0xab; 1024]);
1328        for _ in 0..5 {
1329            kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1330        }
1331        let (bits, ty) = padded_bits(&kilo);
1332        bh.iter(|| {
1333            black_box(Value::from_padded_bits(
1334                &mut BitIter::new(bits.iter().copied()),
1335                ty,
1336            ))
1337        })
1338    }
1339
1340    #[bench]
1341    fn bench_value_create_512_256_padded(bh: &mut Bencher) {
1342        // See comment in bench_value_create_512_256 about this value
1343        let mut s512_256 = Value::product(
1344            Value::from_byte_array([0x12; 64]),
1345            Value::from_byte_array([0x23; 32]),
1346        );
1347        for _ in 0..5 {
1348            s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1349        }
1350        let (bits, ty) = padded_bits(&s512_256);
1351        bh.iter(|| {
1352            black_box(Value::from_padded_bits(
1353                &mut BitIter::new(bits.iter().copied()),
1354                ty,
1355            ))
1356        })
1357    }
1358
1359    // Create values from compact bits
1360    fn compact_bits(v: &Value) -> (Vec<u8>, &Final) {
1361        let (bits, _) = v.iter_compact().collect_bits();
1362        (bits, v.ty.as_ref())
1363    }
1364
1365    #[bench]
1366    fn bench_value_create_u64_compact(bh: &mut Bencher) {
1367        let v = Value::u64(0xff00_00ff_ff00_00ff);
1368        let (bits, ty) = compact_bits(&v);
1369        bh.iter(|| {
1370            black_box(Value::from_compact_bits(
1371                &mut BitIter::new(bits.iter().copied()),
1372                ty,
1373            ))
1374        })
1375    }
1376
1377    #[bench]
1378    fn bench_value_create_u2048_compact(bh: &mut Bencher) {
1379        let v = Value::from_byte_array([0xcd; 2048]);
1380        let (bits, ty) = compact_bits(&v);
1381        bh.iter(|| {
1382            black_box(Value::from_compact_bits(
1383                &mut BitIter::new(bits.iter().copied()),
1384                ty,
1385            ))
1386        })
1387    }
1388
1389    #[bench]
1390    fn bench_value_create_deep_some_compact(bh: &mut Bencher) {
1391        let mut kilo = Value::from_byte_array([0xab; 1024]);
1392        for _ in 0..1000 {
1393            kilo = Value::some(kilo.shallow_clone());
1394        }
1395        let (bits, ty) = compact_bits(&kilo);
1396        bh.iter(|| {
1397            black_box(Value::from_compact_bits(
1398                &mut BitIter::new(bits.iter().copied()),
1399                ty,
1400            ))
1401        })
1402    }
1403
1404    #[bench]
1405    fn bench_value_create_64k_compact(bh: &mut Bencher) {
1406        let mut kilo = Value::from_byte_array([0xab; 1024]);
1407        for _ in 0..5 {
1408            kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1409        }
1410        let (bits, ty) = compact_bits(&kilo);
1411        bh.iter(|| {
1412            black_box(Value::from_compact_bits(
1413                &mut BitIter::new(bits.iter().copied()),
1414                ty,
1415            ))
1416        })
1417    }
1418
1419    #[bench]
1420    fn bench_value_create_512_256_compact(bh: &mut Bencher) {
1421        // See comment in bench_value_create_512_256 about this value
1422        let mut s512_256 = Value::product(
1423            Value::from_byte_array([0x12; 64]),
1424            Value::from_byte_array([0x23; 32]),
1425        );
1426        for _ in 0..5 {
1427            s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1428        }
1429        let (bits, ty) = compact_bits(&s512_256);
1430        bh.iter(|| {
1431            black_box(Value::from_compact_bits(
1432                &mut BitIter::new(bits.iter().copied()),
1433                ty,
1434            ))
1435        })
1436    }
1437
1438    // Display values
1439    #[bench]
1440    fn bench_value_display_u64(bh: &mut Bencher) {
1441        let v = Value::u64(0xff00_00ff_ff00_00ff);
1442        bh.iter(|| black_box(format!("{}", v)))
1443    }
1444
1445    #[bench]
1446    fn bench_value_display_u2024(bh: &mut Bencher) {
1447        let v = Value::from_byte_array([0xcd; 2048]);
1448        bh.iter(|| black_box(format!("{}", v)))
1449    }
1450
1451    #[bench]
1452    fn bench_value_display_deep_some(bh: &mut Bencher) {
1453        let mut kilo = Value::from_byte_array([0xab; 1024]);
1454        for _ in 0..1000 {
1455            kilo = Value::some(kilo.shallow_clone());
1456        }
1457        bh.iter(|| black_box(format!("{}", kilo)))
1458    }
1459
1460    #[bench]
1461    fn bench_value_display_64k(bh: &mut Bencher) {
1462        let mut kilo = Value::from_byte_array([0xab; 1024]);
1463        for _ in 0..5 {
1464            kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1465        }
1466        bh.iter(|| black_box(format!("{}", kilo)))
1467    }
1468
1469    #[bench]
1470    fn bench_value_display_512_256(bh: &mut Bencher) {
1471        // See comment in bench_value_create_512_256 about this value
1472        let mut s512_256 = Value::product(
1473            Value::from_byte_array([0x12; 64]),
1474            Value::from_byte_array([0x23; 32]),
1475        );
1476        for _ in 0..5 {
1477            s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1478        }
1479        bh.iter(|| black_box(format!("{}", s512_256)))
1480    }
1481
1482    // Display values
1483}