Skip to main content

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::{BitCollector, EarlyEndOfStreamError};
11use crate::{BitIter, Tmr};
12
13use hashes::sha256;
14
15use core::{cmp, fmt, iter};
16use std::collections::VecDeque;
17use std::hash::Hash;
18use std::sync::Arc;
19
20/// A Simplicity value.
21#[derive(Clone)]
22pub struct Value {
23    /// The underlying data, in "padded" bit-encoded form, with the leftmost
24    /// bits encoded in the most-significant bits. So e.g. right(unit) is 0x80.
25    ///
26    /// We use the padded form, even though it is space-inefficient (sometimes
27    /// significantly so), for a couple reasons: first, this is the representation
28    /// used by the bit machine, so we want encoding/decoding to be as fast as
29    /// possible. Secondly, when destructuring a value (which we need to do during
30    /// scribing and pruning, at least) it is quite difficult to destructure a
31    /// compact-encoded product, since we would need to determine the compact
32    /// bitlengths of the children, and these quantities are not readily available.
33    inner: Arc<[u8]>,
34    /// An offset, in bits, at which the actual data starts. This is useful
35    /// because it allows constructing sub-values of a value without needing
36    /// to construct a new `inner` with all the bits offset.
37    bit_offset: usize,
38    /// The Simplicity type of the value.
39    ty: Arc<Final>,
40}
41
42/// Reference to a value, or to a sub-value of a value.
43#[derive(Debug, Clone, Copy)]
44pub struct ValueRef<'v> {
45    inner: &'v Arc<[u8]>,
46    bit_offset: usize,
47    ty: &'v Arc<Final>,
48}
49
50// Because two equal values may have different bit offsets, we must manually
51// implement the comparison traits. We do so by first comparing types, which
52// is constant overhead (this just compares TMRs). If those match, we know
53// the lengths and structures match, so we then compare the underlying byte
54// iterators.
55impl PartialEq for Value {
56    fn eq(&self, other: &Self) -> bool {
57        self.ty == other.ty && self.raw_byte_iter().eq(other.raw_byte_iter())
58    }
59}
60impl Eq for Value {}
61
62impl PartialOrd for Value {
63    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
64        Some(self.cmp(other))
65    }
66}
67impl Ord for Value {
68    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
69        self.ty
70            .cmp(&other.ty)
71            .then_with(|| self.raw_byte_iter().cmp(other.raw_byte_iter()))
72    }
73}
74
75impl core::hash::Hash for Value {
76    fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
77        b"Simplicity\x1fValue".hash(h);
78        self.ty.hash(h);
79        for val in self.raw_byte_iter() {
80            val.hash(h);
81        }
82    }
83}
84
85impl DagLike for ValueRef<'_> {
86    type Node = Self;
87
88    fn data(&self) -> &Self {
89        self
90    }
91
92    fn as_dag_node(&self) -> Dag<Self> {
93        if let Some((left, right)) = self.as_product() {
94            Dag::Binary(left, right)
95        } else if let Some(left) = self.as_left() {
96            Dag::Unary(left)
97        } else if let Some(right) = self.as_right() {
98            Dag::Unary(right)
99        } else {
100            assert!(self.ty.is_unit());
101            Dag::Nullary
102        }
103    }
104}
105
106impl<'v> ValueRef<'v> {
107    /// Check if the value is a unit.
108    pub fn is_unit(&self) -> bool {
109        self.ty.is_unit()
110    }
111
112    /// Helper function to read the first bit of a value
113    ///
114    /// If the first bit is not available (e.g. if the value has zero size)
115    /// then returns None.
116    fn first_bit(&self) -> Option<bool> {
117        let mask = if self.bit_offset % 8 == 0 {
118            0x80
119        } else {
120            1 << (7 - self.bit_offset % 8)
121        };
122        let res = self
123            .inner
124            .get(self.bit_offset / 8)
125            .map(|x| x & mask == mask);
126        res
127    }
128
129    /// Access the inner value of a left sum value.
130    pub fn as_left(&self) -> Option<Self> {
131        if self.first_bit() == Some(false) {
132            if let Some((lty, rty)) = self.ty.as_sum() {
133                let sum_width = 1 + cmp::max(lty.bit_width(), rty.bit_width());
134                Some(Self {
135                    inner: self.inner,
136                    bit_offset: self.bit_offset + sum_width - lty.bit_width(),
137                    ty: lty,
138                })
139            } else {
140                None
141            }
142        } else {
143            None
144        }
145    }
146
147    /// Access the inner value of a right sum value.
148    pub fn as_right(&self) -> Option<Self> {
149        if self.first_bit() == Some(true) {
150            if let Some((lty, rty)) = self.ty.as_sum() {
151                let sum_width = 1 + cmp::max(lty.bit_width(), rty.bit_width());
152                Some(Self {
153                    inner: self.inner,
154                    bit_offset: self.bit_offset + sum_width - rty.bit_width(),
155                    ty: rty,
156                })
157            } else {
158                None
159            }
160        } else {
161            None
162        }
163    }
164
165    /// Access the inner values of a product value.
166    pub fn as_product(&self) -> Option<(Self, Self)> {
167        if let Some((lty, rty)) = self.ty.as_product() {
168            Some((
169                Self {
170                    inner: self.inner,
171                    bit_offset: self.bit_offset,
172                    ty: lty,
173                },
174                Self {
175                    inner: self.inner,
176                    bit_offset: self.bit_offset + lty.bit_width(),
177                    ty: rty,
178                },
179            ))
180        } else {
181            None
182        }
183    }
184
185    /// Convert the reference back to a value.
186    pub fn to_value(&self) -> Value {
187        Value {
188            inner: Arc::clone(self.inner),
189            bit_offset: self.bit_offset,
190            ty: Arc::clone(self.ty),
191        }
192    }
193
194    /// Try to convert the value into a word.
195    pub fn to_word(&self) -> Option<Word> {
196        self.ty.as_word().map(|n| Word {
197            value: self.to_value(),
198            n,
199        })
200    }
201
202    /// Yields an iterator over the "raw bytes" of the value.
203    ///
204    /// The returned bytes match the padded bit-encoding of the value. You
205    /// may wish to call [`Self::iter_padded`] instead to obtain the bits,
206    /// but this method is more efficient in some contexts.
207    pub fn raw_byte_iter(&self) -> RawByteIter<'v> {
208        RawByteIter {
209            value: *self,
210            yielded_bytes: 0,
211        }
212    }
213
214    /// Return an iterator over the compact bit encoding of the value.
215    ///
216    /// This encoding is used for writing witness data and for computing IHRs.
217    pub fn iter_compact(&self) -> CompactBitsIter<'v> {
218        CompactBitsIter::new(*self)
219    }
220
221    /// Return an iterator over the padded bit encoding of the value.
222    ///
223    /// This encoding is used to represent the value in the Bit Machine.
224    pub fn iter_padded(&self) -> PreOrderIter<'v> {
225        PreOrderIter {
226            inner: BitIter::new(self.raw_byte_iter()).take(self.ty.bit_width()),
227        }
228    }
229}
230
231pub struct RawByteIter<'v> {
232    value: ValueRef<'v>,
233    yielded_bytes: usize,
234}
235
236impl Iterator for RawByteIter<'_> {
237    type Item = u8;
238    fn next(&mut self) -> Option<Self::Item> {
239        if 8 * self.yielded_bytes >= self.value.ty.bit_width() {
240            None
241        } else if self.value.bit_offset % 8 == 0 {
242            self.yielded_bytes += 1;
243
244            Some(self.value.inner[self.value.bit_offset / 8 + self.yielded_bytes - 1])
245        } else {
246            self.yielded_bytes += 1;
247
248            let ret1 = self.value.inner[self.value.bit_offset / 8 + self.yielded_bytes - 1];
249            let ret2 = self
250                .value
251                .inner
252                .get(self.value.bit_offset / 8 + self.yielded_bytes)
253                .copied()
254                .unwrap_or(0);
255            let bit_offset = self.value.bit_offset % 8;
256            Some((ret1 << bit_offset) | (ret2 >> (8 - bit_offset)))
257        }
258    }
259}
260
261pub struct PreOrderIter<'v> {
262    inner: iter::Take<BitIter<RawByteIter<'v>>>,
263}
264
265impl Iterator for PreOrderIter<'_> {
266    type Item = bool;
267    fn next(&mut self) -> Option<Self::Item> {
268        self.inner.next()
269    }
270}
271
272/// Helper function to right-shift a value by one bit.
273///
274/// This is used for putting a value into a sum type. It takes the value's
275/// bit encoding and current bit offset, and returns a new bit-encoding with
276/// a new bit inserted upfront and a new bit offset.
277fn right_shift_1(inner: &Arc<[u8]>, bit_offset: usize, new_bit: bool) -> (Arc<[u8]>, usize) {
278    // If the current bit offset is nonzero this is super easy: we just
279    // lower the bit offset and call that a fix.
280    if bit_offset > 0 {
281        let new_bit_offset = bit_offset - 1;
282        let mask = 1u8 << (7 - new_bit_offset % 8);
283        let current_bit = inner[new_bit_offset / 8] & mask != 0;
284        if current_bit == new_bit {
285            (Arc::clone(inner), new_bit_offset)
286        } else if new_bit {
287            let mut bx: Box<[u8]> = inner.as_ref().into();
288            bx[new_bit_offset / 8] |= mask;
289            (bx.into(), new_bit_offset)
290        } else {
291            let mut bx: Box<[u8]> = inner.as_ref().into();
292            bx[new_bit_offset / 8] &= !mask;
293            (bx.into(), new_bit_offset)
294        }
295    } else {
296        // If the current bit offset is 0, we just shift everything right by 8
297        // and then do pretty-much the same thing as above. This sometimes will
298        // waste 7 bits, but it avoids needing to iterate through all of `inner`.
299        let mut new = Vec::with_capacity(inner.len() + 1);
300        new.push(u8::from(new_bit));
301        new.extend(inner.iter().copied());
302        (new.into(), 7)
303    }
304}
305
306/// Helper function to copy `nbits` bits from `src`, starting at bit-offset `src_offset`,
307/// into `dst`, starting at bit-offset `dst_offset`.
308///
309/// Thanks ChatGPT for suggesting we extract this function.
310fn copy_bits(src: &[u8], src_offset: usize, dst: &mut [u8], dst_offset: usize, nbits: usize) {
311    // For each bit i in 0..nbits, extract the bit from `src`
312    // and insert it into `dst`.
313    for i in 0..nbits {
314        let bit = (src[(src_offset + i) / 8] >> (7 - (src_offset + i) % 8)) & 1;
315        dst[(dst_offset + i) / 8] |= bit << (7 - (dst_offset + i) % 8);
316    }
317}
318
319/// Helper function to take the product of two values (i.e. their concatenation).
320///
321/// If either `left_inner` or `right_inner` is not provided, it is assumed to be
322/// padding and will be stored as all zeros.
323///
324/// Returns the new bit data and the offset (NOT the length) of the data.
325fn product(
326    left: Option<(&Arc<[u8]>, usize)>,
327    left_bit_length: usize,
328    right: Option<(&Arc<[u8]>, usize)>,
329    right_bit_length: usize,
330) -> (Arc<[u8]>, usize) {
331    if left_bit_length == 0 {
332        if let Some((right, right_bit_offset)) = right {
333            (Arc::clone(right), right_bit_offset)
334        } else if right_bit_length == 0 {
335            (Arc::new([]), 0)
336        } else {
337            (Arc::from(vec![0; right_bit_length.div_ceil(8)]), 0)
338        }
339    } else if right_bit_length == 0 {
340        if let Some((lt, left_bit_offset)) = left {
341            (Arc::clone(lt), left_bit_offset)
342        } else {
343            (Arc::from(vec![0; left_bit_length.div_ceil(8)]), 0)
344        }
345    } else {
346        // Both left and right have nonzero lengths. This is the only "real" case
347        // in which we have to do something beyond cloning Arcs or allocating
348        // zeroed vectors. In this case we left-shift both as much as possible.
349        let mut bx = Box::<[u8]>::from(vec![0; (left_bit_length + right_bit_length).div_ceil(8)]);
350        if let Some((left, left_bit_offset)) = left {
351            copy_bits(left, left_bit_offset, &mut bx, 0, left_bit_length);
352        }
353        if let Some((right, right_bit_offset)) = right {
354            copy_bits(
355                right,
356                right_bit_offset,
357                &mut bx,
358                left_bit_length,
359                right_bit_length,
360            );
361        }
362
363        (bx.into(), 0)
364    }
365}
366
367impl Value {
368    /// Make a cheap copy of the value.
369    pub fn shallow_clone(&self) -> Self {
370        Self {
371            inner: Arc::clone(&self.inner),
372            bit_offset: self.bit_offset,
373            ty: Arc::clone(&self.ty),
374        }
375    }
376
377    /// Access the type of the value.
378    pub fn ty(&self) -> &Final {
379        &self.ty
380    }
381
382    /// Create the unit value.
383    pub fn unit() -> Self {
384        Self {
385            inner: Arc::new([]),
386            bit_offset: 0,
387            ty: Final::unit(),
388        }
389    }
390
391    /// Create a left value that wraps the given `inner` value.
392    pub fn left(inner: Self, right: Arc<Final>) -> Self {
393        let total_width = cmp::max(inner.ty.bit_width(), right.bit_width());
394
395        let (concat, concat_offset) = product(
396            None,
397            total_width - inner.ty.bit_width(),
398            Some((&inner.inner, inner.bit_offset)),
399            inner.ty.bit_width(),
400        );
401        let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, false);
402        Self {
403            inner: new_inner,
404            bit_offset: new_bit_offset,
405            ty: Final::sum(Arc::clone(&inner.ty), right),
406        }
407    }
408
409    /// Create a right value that wraps the given `inner` value.
410    pub fn right(left: Arc<Final>, inner: Self) -> Self {
411        let total_width = cmp::max(left.bit_width(), inner.ty.bit_width());
412        let (concat, concat_offset) = product(
413            None,
414            total_width - inner.ty.bit_width(),
415            Some((&inner.inner, inner.bit_offset)),
416            inner.ty.bit_width(),
417        );
418        let (new_inner, new_bit_offset) = right_shift_1(&concat, concat_offset, true);
419        Self {
420            inner: new_inner,
421            bit_offset: new_bit_offset,
422            ty: Final::sum(left, Arc::clone(&inner.ty)),
423        }
424    }
425
426    /// Create a product value that wraps the given `left` and `right` values.
427    pub fn product(left: Self, right: Self) -> Self {
428        let (new_inner, new_bit_offset) = product(
429            Some((&left.inner, left.bit_offset)),
430            left.ty.bit_width(),
431            Some((&right.inner, right.bit_offset)),
432            right.ty.bit_width(),
433        );
434        Self {
435            inner: new_inner,
436            bit_offset: new_bit_offset,
437            ty: Final::product(Arc::clone(&left.ty), Arc::clone(&right.ty)),
438        }
439    }
440
441    /// Create a none value.
442    pub fn none(right: Arc<Final>) -> Self {
443        Self::left(Value::unit(), right)
444    }
445
446    /// Create a some value.
447    pub fn some(inner: Self) -> Self {
448        Self::right(Final::unit(), inner)
449    }
450
451    /// Create a value of the type `(TWO^8)^<2^(n+1)` for the given `n`, populated
452    /// with the given slice's data.
453    ///
454    /// This type represents "a variable-length buffer of maximum length `2^(n+1) - 1`".
455    /// So for example, setting `n = 5`, the buffer can hold up to 63 bytes.
456    pub fn buffer8_two_n_plus_one(mut n: usize, mut data: &[u8]) -> Result<Self, Buffer8Error> {
457        // This line serves as a sanity check on `n`. After this we can assume that
458        // `1 << n` will not overflow (otherwise would would ty.bit_width be set to?)
459        // Similarly we repeatedly add 1, multiply by 8, etc. But all the values we
460        // compute will be <= ty.bit_width() and therefore not overflow.
461        let ty = Final::buffer8_two_n_plus_one(n).map_err(Buffer8Error::NTooLarge)?;
462
463        debug_assert!(
464            ty.bit_width() > (2 << n) - 1,
465            "sanity check to prove that the below line won't overflow",
466        );
467        if data.len() > (2 << n) - 1 {
468            return Err(Buffer8Error::SliceTooLarge {
469                length: data.len(),
470                n,
471            });
472        }
473
474        let mut dest = vec![0; ty.bit_width().div_ceil(8)];
475        let mut dest_offset = 0;
476        loop {
477            let n_bytes = 1 << n;
478
479            if data.len() & n_bytes != 0 {
480                // split_at will not panic due to SliceTooLarge check above the loop.
481                let (first, rest) = data.split_at(n_bytes);
482                copy_bits(&[0x80], 0, &mut dest, dest_offset, 1);
483                copy_bits(first, 0, &mut dest, dest_offset + 1, 8 * n_bytes);
484                data = rest;
485            };
486            dest_offset += 1 + 8 * n_bytes;
487
488            n = match n.checked_sub(1) {
489                Some(n) => n,
490                None => break,
491            };
492        }
493        debug_assert_eq!(dest_offset, ty.bit_width());
494
495        Ok(Self {
496            inner: Arc::from(dest),
497            bit_offset: 0,
498            ty,
499        })
500    }
501
502    /// Constructs a `Ctx8` from raw parts.
503    ///
504    /// Bear in mind that the count is a count of **bytes**, not a count of **bits**. For the
505    /// context to be valid (i.e. something that could be obtained by a sequence of hashing
506    /// operations), `bytes_hashed % 64` must equal `buffer.len()`.
507    ///
508    /// You may want to obtain a hash engine and call [`Self::ctx8_from_hash_engine`] instead.
509    ///
510    /// # Errors
511    ///
512    /// Errors if the `buffer` exceeds the maximum length of a sha256 buffer (63 bytes).
513    pub fn ctx8(
514        midstate: [u8; 32],
515        bytes_hashed: u64,
516        buffer: &[u8],
517    ) -> Result<Self, Buffer8Error> {
518        Ok(Self::product(
519            Self::buffer8_two_n_plus_one(5, buffer)?,
520            Self::product(Self::u64(bytes_hashed), Self::u256(midstate)),
521        ))
522    }
523
524    /// Converts a SHA256 midstate into a Simplicity value.
525    pub fn ctx8_from_midstate(midstate: sha256::Midstate) -> Self {
526        let (hash, n) = midstate.to_parts();
527        Self::ctx8(hash, n, &[]).expect("0 < 64")
528    }
529
530    /// Converts a SHA256 engine into a Simplicity value.
531    pub fn ctx8_from_hash_engine(engine: &sha256::HashEngine) -> Self {
532        match engine.midstate() {
533            Ok(midstate) => {
534                let (hash, n) = midstate.to_parts();
535                Self::ctx8(hash, n, &[]).expect("0 < 64")
536            }
537            Err(midstate_err) => {
538                let (hash, n) = midstate_err.midstate().to_parts();
539                Self::ctx8(hash, n, midstate_err.unprocessed_bytes()).expect("< 64")
540            }
541        }
542    }
543
544    /// Return the bit length of the value in compact encoding.
545    pub fn compact_len(&self) -> usize {
546        self.iter_compact().count()
547    }
548
549    /// Return the bit length of the value in padded encoding.
550    pub fn padded_len(&self) -> usize {
551        self.ty.bit_width()
552    }
553
554    /// Check if the value is a nested product of units.
555    /// In this case, the value contains no information.
556    pub fn is_empty(&self) -> bool {
557        self.ty.bit_width() == 0
558    }
559
560    /// Check if the value is a unit.
561    pub fn is_unit(&self) -> bool {
562        self.ty.is_unit()
563    }
564
565    /// A reference to this value, which can be recursed over.
566    pub fn as_ref(&self) -> ValueRef<'_> {
567        ValueRef {
568            inner: &self.inner,
569            bit_offset: self.bit_offset,
570            ty: &self.ty,
571        }
572    }
573
574    /// Access the inner value of a left sum value.
575    pub fn as_left(&self) -> Option<ValueRef<'_>> {
576        self.as_ref().as_left()
577    }
578
579    /// Access the inner value of a right sum value.
580    pub fn as_right(&self) -> Option<ValueRef<'_>> {
581        self.as_ref().as_right()
582    }
583
584    /// Access the inner values of a product value.
585    pub fn as_product(&self) -> Option<(ValueRef<'_>, ValueRef<'_>)> {
586        self.as_ref().as_product()
587    }
588
589    /// Create a 1-bit integer.
590    ///
591    /// ## Panics
592    ///
593    /// The value is out of range.
594    pub fn u1(value: u8) -> Self {
595        assert!(value <= 1, "{} out of range for Value::u1", value);
596        Self {
597            inner: Arc::new([value]),
598            bit_offset: 7,
599            ty: Final::two_two_n_fixed::<0>(),
600        }
601    }
602
603    /// Create a 2-bit integer.
604    ///
605    /// ## Panics
606    ///
607    /// The value is out of range.
608    pub fn u2(value: u8) -> Self {
609        assert!(value <= 3, "{} out of range for Value::u2", value);
610        Self {
611            inner: Arc::new([value]),
612            bit_offset: 6,
613            ty: Final::two_two_n_fixed::<1>(),
614        }
615    }
616
617    /// Create a 4-bit integer.
618    ///
619    /// ## Panics
620    ///
621    /// The value is ouf of range.
622    pub fn u4(value: u8) -> Self {
623        assert!(value <= 15, "{} out of range for Value::u2", value);
624        Self {
625            inner: Arc::new([value]),
626            bit_offset: 4,
627            ty: Final::two_two_n_fixed::<2>(),
628        }
629    }
630
631    /// Create an 8-bit integer.
632    pub fn u8(value: u8) -> Self {
633        Self {
634            inner: Arc::new([value]),
635            bit_offset: 0,
636            ty: Final::two_two_n_fixed::<3>(),
637        }
638    }
639
640    /// Create a 16-bit integer.
641    pub fn u16(bytes: u16) -> Self {
642        Self {
643            inner: Arc::new(bytes.to_be_bytes()),
644            bit_offset: 0,
645            ty: Final::two_two_n_fixed::<4>(),
646        }
647    }
648
649    /// Create a 32-bit integer.
650    pub fn u32(bytes: u32) -> Self {
651        Self {
652            inner: Arc::new(bytes.to_be_bytes()),
653            bit_offset: 0,
654            ty: Final::two_two_n_fixed::<5>(),
655        }
656    }
657
658    /// Create a 64-bit integer.
659    pub fn u64(bytes: u64) -> Self {
660        Self {
661            inner: Arc::new(bytes.to_be_bytes()),
662            bit_offset: 0,
663            ty: Final::two_two_n_fixed::<6>(),
664        }
665    }
666
667    /// Create a 128-bit integer.
668    pub fn u128(bytes: u128) -> Self {
669        Self {
670            inner: Arc::new(bytes.to_be_bytes()),
671            bit_offset: 0,
672            ty: Final::two_two_n_fixed::<7>(),
673        }
674    }
675
676    /// Create a 256-bit integer.
677    pub fn u256(bytes: [u8; 32]) -> Self {
678        Self {
679            inner: Arc::new(bytes),
680            bit_offset: 0,
681            ty: Final::two_two_n_fixed::<8>(),
682        }
683    }
684
685    /// Create a 512-bit integer.
686    pub fn u512(bytes: [u8; 64]) -> Self {
687        Self {
688            inner: Arc::new(bytes),
689            bit_offset: 0,
690            ty: Final::two_two_n_fixed::<9>(),
691        }
692    }
693
694    /// Create a value from a byte array.
695    ///
696    /// ## Panics
697    ///
698    /// The array length is not a power of two.
699    pub fn from_byte_array<const N: usize>(bytes: [u8; N]) -> Self {
700        assert!(N.is_power_of_two(), "Array length must be a power of two");
701        let mut values: VecDeque<_> = bytes.into_iter().map(Value::u8).collect();
702
703        while values.len() > 1 {
704            let mut alt_values = VecDeque::with_capacity(values.len() / 2);
705
706            while let (Some(left), Some(right)) = (values.pop_front(), values.pop_front()) {
707                alt_values.push_back(Value::product(left, right));
708            }
709
710            values = alt_values;
711        }
712
713        values.into_iter().next().unwrap()
714    }
715
716    /// Yields an iterator over the "raw bytes" of the value.
717    ///
718    /// The returned bytes match the padded bit-encoding of the value. You
719    /// may wish to call [`Self::iter_padded`] instead to obtain the bits,
720    /// but this method is more efficient in some contexts.
721    pub fn raw_byte_iter(&self) -> RawByteIter<'_> {
722        self.as_ref().raw_byte_iter()
723    }
724
725    /// Return an iterator over the compact bit encoding of the value.
726    ///
727    /// This encoding is used for writing witness data and for computing IHRs.
728    pub fn iter_compact(&self) -> CompactBitsIter<'_> {
729        self.as_ref().iter_compact()
730    }
731
732    /// Return an iterator over the padded bit encoding of the value.
733    ///
734    /// This encoding is used to represent the value in the Bit Machine.
735    pub fn iter_padded(&self) -> PreOrderIter<'_> {
736        self.as_ref().iter_padded()
737    }
738
739    /// Check if the value is of the given type.
740    pub fn is_of_type(&self, ty: &Final) -> bool {
741        self.ty.as_ref() == ty
742    }
743
744    /// Get the zero value for the given type.
745    ///
746    /// The zero value serializes to a string of zeroes.
747    ///
748    /// ## Construction
749    ///
750    /// - `zero( 1 )` = `()`
751    /// - `zero( A + B )` = `zero(A)`
752    /// - `zero( A × B )` = `zero(A) × zero(B)`
753    pub fn zero(ty: &Final) -> Self {
754        Self {
755            inner: Arc::from(vec![0; ty.bit_width().div_ceil(8)]),
756            bit_offset: 0,
757            ty: Arc::new(ty.clone()),
758        }
759    }
760
761    /// Try to convert the value into a word.
762    ///
763    /// The value is cheaply cloned.
764    pub fn to_word(&self) -> Option<Word> {
765        self.ty.as_word().map(|n| Word {
766            value: self.shallow_clone(),
767            n,
768        })
769    }
770
771    /// Prune the value down to the given type.
772    ///
773    /// The pruned type must be _smaller than or equal to_ the current type of the value.
774    /// Otherwise, this method returns `None`.
775    ///
776    /// ## Smallness
777    ///
778    /// - `T` ≤ `T` for all types `T`
779    /// - `1` ≤ `T` for all types `T`
780    /// - `A1 + B1` ≤ `A2 + B2` if `A1` ≤ `A2` and `B1` ≤ `B2`
781    /// - `A1 × B1` ≤ `A2 × B2` if `A1` ≤ `A2` and `B1` ≤ `B2`
782    ///
783    /// ## Pruning
784    ///
785    /// - `prune( v: T, 1 )` = `(): 1`
786    /// - `prune( L(l): A1 + B1, A2 + B2 )` = `prune(l: A1, A2) : A2 + B2`
787    /// - `prune( R(r): A1 + B1, A2 + B2 )` = `prune(r: B1, B2) : A2 + B2`
788    /// - `prune( (l, r): A1 × B1, A2 × B2 )` = `( prune(l: A1, A2), prune(r: B1, B2): A2 × B2`
789    pub fn prune(&self, pruned_ty: &Final) -> Option<Self> {
790        enum Task<'v, 'ty> {
791            Prune(ValueRef<'v>, &'ty Final),
792            MakeLeft(Arc<Final>),
793            MakeRight(Arc<Final>),
794            MakeProduct,
795        }
796
797        let mut stack = vec![Task::Prune(self.as_ref(), pruned_ty)];
798        let mut output = vec![];
799
800        while let Some(task) = stack.pop() {
801            match task {
802                Task::Prune(value, pruned_ty) if value.ty.as_ref() == pruned_ty => {
803                    output.push(value.to_value())
804                }
805                Task::Prune(value, pruned_ty) => match pruned_ty.bound() {
806                    CompleteBound::Unit => output.push(Value::unit()),
807                    CompleteBound::Sum(l_ty, r_ty) => {
808                        if let Some(l_value) = value.as_left() {
809                            stack.push(Task::MakeLeft(Arc::clone(r_ty)));
810                            stack.push(Task::Prune(l_value, l_ty));
811                        } else {
812                            let r_value = value.as_right()?;
813                            stack.push(Task::MakeRight(Arc::clone(l_ty)));
814                            stack.push(Task::Prune(r_value, r_ty));
815                        }
816                    }
817                    CompleteBound::Product(l_ty, r_ty) => {
818                        let (l_value, r_value) = value.as_product()?;
819                        stack.push(Task::MakeProduct);
820                        stack.push(Task::Prune(r_value, r_ty));
821                        stack.push(Task::Prune(l_value, l_ty));
822                    }
823                },
824                Task::MakeLeft(r_ty) => {
825                    let l_value = output.pop().unwrap();
826                    output.push(Value::left(l_value, r_ty));
827                }
828                Task::MakeRight(l_ty) => {
829                    let r_value = output.pop().unwrap();
830                    output.push(Value::right(l_ty, r_value));
831                }
832                Task::MakeProduct => {
833                    let r_value = output.pop().unwrap();
834                    let l_value = output.pop().unwrap();
835                    output.push(Value::product(l_value, r_value));
836                }
837            }
838        }
839
840        debug_assert_eq!(output.len(), 1);
841        output.pop()
842    }
843}
844
845impl fmt::Debug for Value {
846    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
847        f.debug_struct("Value")
848            .field("value", &format_args!("{}", self))
849            .field("ty", &self.ty)
850            .field("raw_value", &self.inner)
851            .field("raw_bit_offset", &self.bit_offset)
852            .finish()
853    }
854}
855
856impl fmt::Display for Value {
857    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
858        // This is a copy of the logic inside `CompactBitsIter` except
859        // that we handle products more explicitly.
860        enum S<'v> {
861            Disp(ValueRef<'v>),
862            DispCh(char),
863        }
864
865        let mut stack = Vec::with_capacity(1024);
866        // Next node to visit.
867        stack.push(S::Disp(self.as_ref()));
868
869        'main_loop: while let Some(next) = stack.pop() {
870            let value = match next {
871                S::Disp(ref value) => value,
872                S::DispCh(ch) => {
873                    write!(f, "{}", ch)?;
874                    continue;
875                }
876            };
877
878            if value.is_unit() {
879                f.write_str("ε")?;
880            } else {
881                // First, write any bitstrings out
882                for tmr in &Tmr::TWO_TWO_N {
883                    if value.ty.tmr() == *tmr {
884                        if value.ty.bit_width() < 4 {
885                            f.write_str("0b")?;
886                            for bit in value.iter_padded() {
887                                f.write_str(if bit { "1" } else { "0" })?;
888                            }
889                        } else {
890                            f.write_str("0x")?;
891                            // Annoyingly `array_chunks` is unstable so we have to do it manually
892                            // https://github.com/rust-lang/rust/issues/100450
893                            let mut iter = value.iter_padded();
894                            while let (Some(a), Some(b), Some(c), Some(d)) =
895                                (iter.next(), iter.next(), iter.next(), iter.next())
896                            {
897                                let n = (u8::from(a) << 3)
898                                    + (u8::from(b) << 2)
899                                    + (u8::from(c) << 1)
900                                    + u8::from(d);
901                                write!(f, "{:x}", n)?;
902                            }
903                        }
904                        continue 'main_loop;
905                    }
906                }
907
908                // If we don't have a bitstring, then write out the explicit value.
909                if let Some(l_value) = value.as_left() {
910                    f.write_str("L(")?;
911                    stack.push(S::DispCh(')'));
912                    stack.push(S::Disp(l_value));
913                } else if let Some(r_value) = value.as_right() {
914                    f.write_str("R(")?;
915                    stack.push(S::DispCh(')'));
916                    stack.push(S::Disp(r_value));
917                } else if let Some((l_value, r_value)) = value.as_product() {
918                    stack.push(S::DispCh(')'));
919                    stack.push(S::Disp(r_value));
920                    stack.push(S::DispCh(','));
921                    stack.push(S::Disp(l_value));
922                    stack.push(S::DispCh('('));
923                } else {
924                    unreachable!()
925                }
926            }
927        }
928        Ok(())
929    }
930}
931
932/// An iterator over the bits of the compact encoding of a [`Value`].
933#[derive(Debug, Clone)]
934pub struct CompactBitsIter<'v> {
935    stack: Vec<ValueRef<'v>>,
936}
937
938impl<'v> CompactBitsIter<'v> {
939    /// Create an iterator over the bits of the compact encoding of the `value`.
940    fn new(value: ValueRef<'v>) -> Self {
941        Self { stack: vec![value] }
942    }
943}
944
945impl Iterator for CompactBitsIter<'_> {
946    type Item = bool;
947
948    fn next(&mut self) -> Option<Self::Item> {
949        while let Some(value) = self.stack.pop() {
950            if value.ty.bit_width() == 0 {
951                // NOP
952            } else if let Some(l_value) = value.as_left() {
953                self.stack.push(l_value);
954                return Some(false);
955            } else if let Some(r_value) = value.as_right() {
956                self.stack.push(r_value);
957                return Some(true);
958            } else if let Some((l_value, r_value)) = value.as_product() {
959                self.stack.push(r_value);
960                self.stack.push(l_value);
961            }
962        }
963
964        None
965    }
966}
967
968impl Value {
969    /// Decode a value of the given type from its compact bit encoding.
970    pub fn from_compact_bits<I: Iterator<Item = u8>>(
971        bits: &mut BitIter<I>,
972        ty: &Final,
973    ) -> Result<Self, EarlyEndOfStreamError> {
974        enum State<'a> {
975            ProcessType(&'a Final),
976            DoSumL(Arc<Final>),
977            DoSumR(Arc<Final>),
978            DoProduct,
979        }
980
981        let mut stack = vec![State::ProcessType(ty)];
982        let mut result_stack = vec![];
983        while let Some(state) = stack.pop() {
984            match state {
985                State::ProcessType(ty) if ty.has_padding() => match ty.bound() {
986                    CompleteBound::Unit => result_stack.push(Value::unit()),
987                    CompleteBound::Sum(ref l, ref r) => {
988                        if !bits.next().ok_or(EarlyEndOfStreamError)? {
989                            stack.push(State::DoSumL(Arc::clone(r)));
990                            stack.push(State::ProcessType(l));
991                        } else {
992                            stack.push(State::DoSumR(Arc::clone(l)));
993                            stack.push(State::ProcessType(r));
994                        }
995                    }
996                    CompleteBound::Product(ref l, ref r) => {
997                        stack.push(State::DoProduct);
998                        stack.push(State::ProcessType(r));
999                        stack.push(State::ProcessType(l));
1000                    }
1001                },
1002                State::ProcessType(ty) => {
1003                    // no padding no problem
1004                    result_stack.push(Value::from_padded_bits(bits, ty)?);
1005                }
1006                State::DoSumL(r) => {
1007                    let val = result_stack.pop().unwrap();
1008                    result_stack.push(Value::left(val, r));
1009                }
1010                State::DoSumR(l) => {
1011                    let val = result_stack.pop().unwrap();
1012                    result_stack.push(Value::right(l, val));
1013                }
1014                State::DoProduct => {
1015                    let val_r = result_stack.pop().unwrap();
1016                    let val_l = result_stack.pop().unwrap();
1017                    result_stack.push(Value::product(val_l, val_r));
1018                }
1019            }
1020        }
1021        debug_assert_eq!(result_stack.len(), 1);
1022        Ok(result_stack.pop().unwrap())
1023    }
1024
1025    /// Decode a value of the given type from its padded bit encoding.
1026    pub fn from_padded_bits<I: Iterator<Item = u8>>(
1027        bits: &mut BitIter<I>,
1028        ty: &Final,
1029    ) -> Result<Self, EarlyEndOfStreamError> {
1030        const MAX_INITIAL_ALLOC: usize = 32 * 1024 * 1024; // 4 megabytes
1031
1032        let cap = cmp::min(MAX_INITIAL_ALLOC, ty.bit_width().div_ceil(8));
1033        let mut blob = Vec::with_capacity(cap);
1034        for _ in 0..ty.bit_width() / 8 {
1035            blob.push(bits.read_u8()?);
1036        }
1037        let mut last = 0u8;
1038        for i in 0..ty.bit_width() % 8 {
1039            if bits.read_bit()? {
1040                last |= 1 << (7 - i);
1041            }
1042        }
1043        blob.push(last);
1044
1045        Ok(Value {
1046            inner: blob.into(),
1047            bit_offset: 0,
1048            ty: Arc::new(ty.clone()),
1049        })
1050    }
1051}
1052
1053/// A Simplicity word. A value of type `TWO^(2^n)` for some `0 ≤ n < 32`.
1054#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
1055pub struct Word {
1056    /// Value of type `TWO^(2^n)`.
1057    value: Value,
1058    /// 0 ≤ n < 32.
1059    n: u8,
1060}
1061
1062macro_rules! construct_word_fallible {
1063    ($name: ident, $n: expr, $text: expr) => {
1064        #[doc = "Create"]
1065        #[doc = $text]
1066        #[doc = "word.\n\n"]
1067        #[doc = "## Panics\n"]
1068        #[doc = "The value is ouf of range."]
1069        pub fn $name(bit: u8) -> Self {
1070            Self {
1071                value: Value::$name(bit),
1072                n: $n,
1073            }
1074        }
1075    };
1076}
1077
1078macro_rules! construct_word {
1079    ($name: ident, $ty: ty, $n: expr, $text: expr) => {
1080        #[doc = "Create"]
1081        #[doc = $text]
1082        #[doc = "word."]
1083        pub fn $name(bit: $ty) -> Self {
1084            Self {
1085                value: Value::$name(bit),
1086                n: $n,
1087            }
1088        }
1089    };
1090}
1091
1092impl Word {
1093    /// Concatenate two words into a larger word.
1094    ///
1095    /// Both words have to have the same length, which is 2^n bits.
1096    /// The resulting word will be 2^(n + 1) bits long.
1097    ///
1098    /// Returns `None` if the words differ in length.
1099    ///
1100    /// Returns `None` if the words are already 2^31 bits long
1101    /// _(the resulting word would be longer than 2^31 bits, which is not supported)_.
1102    pub fn product(self, right: Self) -> Option<Self> {
1103        if self.n == right.n && self.n < 30 {
1104            Some(Self {
1105                value: Value::product(self.value, right.value),
1106                n: self.n + 1,
1107            })
1108        } else {
1109            None
1110        }
1111    }
1112
1113    construct_word_fallible!(u1, 0, "a 1-bit");
1114    construct_word_fallible!(u2, 1, "a 2-bit");
1115    construct_word_fallible!(u4, 2, "a 4-bit");
1116    construct_word!(u8, u8, 3, "an 8-bit");
1117    construct_word!(u16, u16, 4, "a 16-bit");
1118    construct_word!(u32, u32, 5, "a 32-bit");
1119    construct_word!(u64, u64, 6, "a 64-bit");
1120    construct_word!(u128, u128, 7, "a 128-bit");
1121    construct_word!(u256, [u8; 32], 8, "a 256-bit");
1122    construct_word!(u512, [u8; 64], 9, "a 512-bit");
1123
1124    /// Make a cheap copy of the word.
1125    pub fn shallow_clone(&self) -> Self {
1126        Self {
1127            value: self.value.shallow_clone(),
1128            n: self.n,
1129        }
1130    }
1131
1132    /// Access the value of the word.
1133    pub fn as_value(&self) -> &Value {
1134        &self.value
1135    }
1136
1137    /// The word is of type `TWO^(2^n)`. Return `n`.
1138    pub fn n(&self) -> usize {
1139        usize::from(self.n)
1140    }
1141
1142    /// Return the bit length of the word.
1143    ///
1144    /// The word is of type `TWO^(2^n)`. Return `2^n`.
1145    #[allow(clippy::len_without_is_empty)]
1146    pub fn len(&self) -> usize {
1147        2usize.pow(u32::from(self.n))
1148    }
1149
1150    /// Return an iterator over the bit encoding of the word.
1151    ///
1152    /// Words have no padding, so their compact encoding is the same as the padded encoding.
1153    /// The universal encoding can be used in all situations.
1154    pub fn iter(&self) -> impl Iterator<Item = bool> + '_ {
1155        self.value.iter_compact()
1156    }
1157
1158    /// Decode a word of type `TWO^(2^n)` from bits.
1159    ///
1160    /// ## Panics
1161    ///
1162    /// n is greater than 31.
1163    pub fn from_bits<I: Iterator<Item = u8>>(
1164        bits: &mut BitIter<I>,
1165        n: u32,
1166    ) -> Result<Self, EarlyEndOfStreamError> {
1167        let n8 = u8::try_from(n).unwrap_or(u8::MAX); // u8::MAX will error on next line
1168        let Ok(ty) = Final::two_two_n(usize::from(n8)) else {
1169            panic!("TWO^(2^{n}) is not supported as a word type");
1170        };
1171        let value = Value::from_compact_bits(bits, &ty)?;
1172        Ok(Self { value, n: n8 })
1173    }
1174}
1175
1176impl fmt::Debug for Word {
1177    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1178        fmt::Display::fmt(self, f)
1179    }
1180}
1181
1182impl fmt::Display for Word {
1183    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1184        use hex::DisplayHex;
1185
1186        if let Ok(hex) = self.iter().try_collect_bytes() {
1187            write!(f, "0x{}", hex.as_hex())
1188        } else {
1189            f.write_str("0b")?;
1190            for bit in self.iter() {
1191                match bit {
1192                    false => f.write_str("0")?,
1193                    true => f.write_str("1")?,
1194                }
1195            }
1196            Ok(())
1197        }
1198    }
1199}
1200
1201/// Slice exceeded the maximum capacity of the buffer type in [`Value::buffer8_two_n_plus_one`].
1202#[derive(Clone, PartialEq, Eq, Debug)]
1203pub enum Buffer8Error {
1204    NTooLarge(crate::types::TypeTooLargeError),
1205    SliceTooLarge { length: usize, n: usize },
1206}
1207
1208impl fmt::Display for Buffer8Error {
1209    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1210        match *self {
1211            Self::NTooLarge(_) => f.write_str("failed to construct (sub)type of buffer"),
1212            Self::SliceTooLarge { length, n } => write!(
1213                f,
1214                "slice of length {} too long for type (TWO^8)^<2^({}+1) (maximum {})",
1215                length,
1216                n,
1217                (1 << (n + 1)) - 1,
1218            ),
1219        }
1220    }
1221}
1222
1223impl std::error::Error for Buffer8Error {
1224    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1225        match *self {
1226            Self::NTooLarge(ref e) => Some(e),
1227            Self::SliceTooLarge { .. } => None,
1228        }
1229    }
1230}
1231
1232#[cfg(test)]
1233mod tests {
1234    use super::*;
1235    use crate::bit_encoding::{BitCollector as _, BitIter};
1236    use crate::jet::type_name::TypeName;
1237
1238    #[test]
1239    fn value_len() {
1240        let v = Value::u4(6);
1241        let s_v = Value::some(v.shallow_clone());
1242        let n_v = Value::none(Final::two_two_n_fixed::<2>());
1243
1244        assert_eq!(v.compact_len(), 4);
1245        assert_eq!(v.padded_len(), 4);
1246        assert_eq!(s_v.compact_len(), 5);
1247        assert_eq!(s_v.padded_len(), 5);
1248        assert_eq!(n_v.compact_len(), 1);
1249        assert_eq!(n_v.padded_len(), 5);
1250    }
1251
1252    #[test]
1253    fn value_display() {
1254        // Only test a couple values becasue we probably want to change this
1255        // at some point and will have to redo this test.
1256        assert_eq!(Value::u1(0).to_string(), "0b0",);
1257        assert_eq!(Value::u1(1).to_string(), "0b1",);
1258        assert_eq!(Value::u4(6).to_string(), "0x6",);
1259    }
1260
1261    #[test]
1262    fn is_of_type() {
1263        let value_typename = [
1264            (Value::unit(), TypeName(b"1")),
1265            (Value::left(Value::unit(), Final::unit()), TypeName(b"+11")),
1266            (Value::right(Final::unit(), Value::unit()), TypeName(b"+11")),
1267            (
1268                Value::left(Value::unit(), Final::two_two_n_fixed::<8>()),
1269                TypeName(b"+1h"),
1270            ),
1271            (
1272                Value::right(Final::two_two_n_fixed::<8>(), Value::unit()),
1273                TypeName(b"+h1"),
1274            ),
1275            (
1276                Value::product(Value::unit(), Value::unit()),
1277                TypeName(b"*11"),
1278            ),
1279            (Value::u8(u8::MAX), TypeName(b"c")),
1280            (Value::u64(u64::MAX), TypeName(b"l")),
1281        ];
1282
1283        for (value, typename) in value_typename {
1284            let ty = typename.to_final();
1285            assert!(value.is_of_type(ty.as_ref()));
1286        }
1287    }
1288
1289    #[test]
1290    fn prune_regression_1() {
1291        // Found this when fuzzing Elements; unsure how to reduce it further.
1292        let nontrivial_sum = Value::product(
1293            Value::right(Final::two_two_n_fixed::<4>(), Value::u16(0)),
1294            Value::u8(0),
1295        );
1296        // Formatting should succeed and have no effect.
1297        let _ = format!("{nontrivial_sum}");
1298        // Pruning should succeed and have no effect.
1299        assert_eq!(
1300            nontrivial_sum.prune(nontrivial_sum.ty()),
1301            Some(nontrivial_sum)
1302        );
1303    }
1304
1305    #[test]
1306    fn prune() {
1307        let test_vectors = [
1308            (Value::unit(), Value::unit()),
1309            (Value::u64(42), Value::unit()),
1310            (
1311                Value::left(Value::u64(42), Final::u64()),
1312                Value::left(Value::u64(42), Final::unit()),
1313            ),
1314            (
1315                Value::right(Final::u64(), Value::u64(1337)),
1316                Value::right(Final::unit(), Value::u64(1337)),
1317            ),
1318            (
1319                Value::product(Value::u64(42), Value::u64(1337)),
1320                Value::product(Value::u64(42), Value::unit()),
1321            ),
1322            (
1323                Value::product(Value::u64(42), Value::u64(1337)),
1324                Value::product(Value::unit(), Value::u64(1337)),
1325            ),
1326        ];
1327
1328        for (value, expected_pruned_value) in test_vectors {
1329            assert_eq!(
1330                value.prune(expected_pruned_value.ty()),
1331                Some(expected_pruned_value)
1332            );
1333        }
1334
1335        let bad_test_vectors = [
1336            (Value::unit(), Final::u1()),
1337            (
1338                Value::product(Value::unit(), Value::unit()),
1339                Final::sum(Final::unit(), Final::unit()),
1340            ),
1341            (
1342                Value::left(Value::unit(), Final::unit()),
1343                Final::product(Final::unit(), Final::unit()),
1344            ),
1345            (
1346                Value::right(Final::unit(), Value::unit()),
1347                Final::product(Final::unit(), Final::unit()),
1348            ),
1349        ];
1350
1351        for (value, pruned_ty) in bad_test_vectors {
1352            assert_eq!(value.prune(&pruned_ty), None);
1353        }
1354    }
1355
1356    #[test]
1357    fn zero_value() {
1358        let test_vectors = [
1359            (Final::unit(), Value::unit()),
1360            (Final::u8(), Value::u8(0)),
1361            (Final::u64(), Value::u64(0)),
1362            (
1363                Final::product(Final::u16(), Final::u32()),
1364                Value::product(Value::u16(0), Value::u32(0)),
1365            ),
1366            (
1367                Final::sum(Final::unit(), Final::u64()),
1368                Value::left(Value::unit(), Final::u64()),
1369            ),
1370            (
1371                Final::product(Final::unit(), Final::unit()),
1372                Value::product(Value::unit(), Value::unit()),
1373            ),
1374        ];
1375
1376        for (ty, expected_default_value) in test_vectors {
1377            assert_eq!(Value::zero(&ty), expected_default_value);
1378        }
1379    }
1380
1381    #[test]
1382    fn compact_round_trip() {
1383        let v = Value::u64(0xff00_00ff_ff00_00ff);
1384        let (bits, _) = v.iter_compact().collect_bits();
1385        let mut iter = BitIter::new(bits.into_iter());
1386        let new_v = Value::from_compact_bits(&mut iter, &v.ty).unwrap();
1387        assert_eq!(v, new_v);
1388    }
1389
1390    #[test]
1391    fn padded_round_trip() {
1392        let v = Value::u64(0xff00_00ff_ff00_00ff);
1393        let (bits, _) = v.iter_padded().collect_bits();
1394        let mut iter = BitIter::new(bits.into_iter());
1395        let new_v = Value::from_padded_bits(&mut iter, &v.ty).unwrap();
1396        assert_eq!(v, new_v);
1397    }
1398
1399    // --- Bug regression tests for right_shift_1 when new_bit=false ---
1400    //
1401    // right_shift_1(inner, bit_offset > 0, new_bit=false) is supposed to insert
1402    // a 0 (Left tag) at position bit_offset-1 by decrementing bit_offset.  The bug
1403    // is that it clones the Arc without clearing that position, so any pre-existing
1404    // 1-bit at bit_offset-1 corrupts the Left tag, causing the value to read as
1405    // Right instead of Left.
1406    //
1407    // The dirty bit originates from product sub-value extraction: as_product()
1408    // returns ValueRef children that share the parent buffer.  The right child has
1409    // bit_offset = parent.bit_offset + left_bit_width, so every 1-bit encoded by
1410    // the left component sits "before" the right child's logical start.  When that
1411    // right child is later wrapped in Left, right_shift_1 may see a stale 1-bit.
1412
1413    /// Simplest direct construction: extract the right sub-value of a product
1414    /// whose left component has 1-bits, then wrap the sub-value in Left.
1415    ///
1416    /// `product(Right(u1(1)), Right(u1(0)))` encodes as [0xE0] at bit_offset=0:
1417    ///   bits 0..=1  = Right(u1(1))  = 1, 1   ← left component
1418    ///   bits 2..=3  = Right(u1(0))  = 1, 0   ← right component (bit_offset=2)
1419    ///
1420    /// Wrapping the right sub-value (bit_offset=2 in [0xE0]) in Left calls
1421    /// right_shift_1(false) which should clear bit 1.  The bug leaves bit 1 = 1,
1422    /// so the result reads as Right instead of Left.
1423    #[test]
1424    fn left_tag_not_corrupted_by_dirty_buffer() {
1425        let product_val = Value::product(
1426            Value::right(Final::u1(), Value::u1(1)), // encodes bits 0,1 as 1,1
1427            Value::right(Final::u1(), Value::u1(0)), // starts at bit_offset=2
1428        );
1429
1430        let (_, right_sub) = product_val.as_product().unwrap();
1431        // right_sub shares [0xE0]; bit at position 1 (before its start) is 1.
1432        let right_sub_owned = right_sub.to_value();
1433
1434        let left_val = Value::left(right_sub_owned, Final::unit());
1435
1436        assert!(
1437            left_val.as_left().is_some(),
1438            "BUG: Left tag corrupted — right_shift_1(false) did not clear dirty bit; \
1439             value reads as Right instead of Left"
1440        );
1441        assert!(
1442            left_val.as_right().is_none(),
1443            "BUG: Left tag corrupted — as_right() should return None for a Left value"
1444        );
1445    }
1446
1447    /// Verify the dirty-buffer bug at the bit level: the first padded bit of a
1448    /// Left value must always be 0 (the Left discriminant).
1449    #[test]
1450    fn left_tag_first_padded_bit_is_zero() {
1451        let product_val = Value::product(
1452            Value::right(Final::u1(), Value::u1(1)),
1453            Value::right(Final::u1(), Value::u1(0)),
1454        );
1455
1456        let (_, right_sub) = product_val.as_product().unwrap();
1457        let left_val = Value::left(right_sub.to_value(), Final::unit());
1458
1459        let first_bit = left_val.iter_padded().next();
1460        assert_eq!(
1461            first_bit,
1462            Some(false),
1463            "BUG: first padded bit of Left value is {:?}, expected Some(false)",
1464            first_bit
1465        );
1466    }
1467
1468    /// End-to-end via prune: pruning can extract a sub-value via to_value() that
1469    /// shares the parent buffer and has 1-bits before its logical start.  When
1470    /// prune then calls Value::left() on it (Task::MakeLeft), the bug corrupts
1471    /// the Left tag.
1472    ///
1473    /// Original:  Left(product(Right(u1(1)), Right(u1(0))))
1474    ///            type: ((u1+u1) * (u1+u1)) + unit
1475    ///
1476    /// Pruned to: (unit * (u1+u1)) + unit
1477    ///
1478    /// The right component of the inner product keeps its type (u1+u1) unchanged,
1479    /// so prune returns it via to_value() — sharing the same dirty buffer.
1480    /// MakeLeft then wraps it, triggering the bug.
1481    #[test]
1482    fn prune_does_not_corrupt_left_tag_via_shared_buffer() {
1483        let original = Value::left(
1484            Value::product(
1485                Value::right(Final::u1(), Value::u1(1)),
1486                Value::right(Final::u1(), Value::u1(0)),
1487            ),
1488            Final::unit(),
1489        );
1490
1491        // Shrink the left component: (u1+u1)*(u1+u1)  →  unit*(u1+u1).
1492        // The right sub-value of the product keeps type u1+u1 (matches exactly),
1493        // so prune returns it via to_value() with the dirty shared buffer intact.
1494        let pruned_ty = Final::sum(
1495            Final::product(Final::unit(), Final::sum(Final::u1(), Final::u1())),
1496            Final::unit(),
1497        );
1498
1499        let pruned = original
1500            .prune(&pruned_ty)
1501            .expect("prune returned None; the target type is compatible");
1502
1503        assert!(
1504            pruned.as_left().is_some(),
1505            "BUG: prune corrupted the Left tag — right_shift_1(false) did not clear \
1506             a dirty bit from the shared product buffer; value reads as Right"
1507        );
1508    }
1509
1510    #[test]
1511    fn buffer8_two_n_plus_one() {
1512        // n = 0 is just Option<u8>
1513        assert_eq!(
1514            Value::buffer8_two_n_plus_one(0, &[]).unwrap(),
1515            Value::none(Final::two_two_n_fixed::<3>()),
1516        );
1517        assert_eq!(
1518            Value::buffer8_two_n_plus_one(0, &[3]).unwrap(),
1519            Value::some(Value::u8(3)),
1520        );
1521        // n = 1 is Option<[u8; 2]> x Option<u8>
1522        assert_eq!(
1523            Value::buffer8_two_n_plus_one(1, &[]).unwrap(),
1524            Value::product(
1525                Value::none(Final::two_two_n_fixed::<4>()),
1526                Value::none(Final::two_two_n_fixed::<3>()),
1527            ),
1528        );
1529        assert_eq!(
1530            Value::buffer8_two_n_plus_one(1, &[0x99]).unwrap(),
1531            Value::product(
1532                Value::none(Final::two_two_n_fixed::<4>()),
1533                Value::some(Value::u8(0x99)),
1534            ),
1535        );
1536        assert_eq!(
1537            Value::buffer8_two_n_plus_one(1, &[0x12, 0x34]).unwrap(),
1538            Value::product(
1539                Value::some(Value::u16(0x1234)),
1540                Value::none(Final::two_two_n_fixed::<3>()),
1541            ),
1542        );
1543        assert_eq!(
1544            Value::buffer8_two_n_plus_one(1, &[0x12, 0x34, 0xff]).unwrap(),
1545            Value::product(
1546                Value::some(Value::u16(0x1234)),
1547                Value::some(Value::u8(0xff)),
1548            ),
1549        );
1550
1551        // Then let's do a "big" one.
1552        let sample: [u8; 49] = *b"there are strange things done in the midnight sun";
1553        Value::buffer8_two_n_plus_one(0, &sample).unwrap_err();
1554        Value::buffer8_two_n_plus_one(4, &sample).unwrap_err();
1555        assert_eq!(
1556            Value::buffer8_two_n_plus_one(5, &sample).unwrap(),
1557            Value::product(
1558                Value::some(Value::from_byte_array(*b"there are strange things done in")),
1559                Value::product(
1560                    Value::some(Value::from_byte_array(*b" the midnight su")),
1561                    Value::product(
1562                        Value::none(Final::two_two_n_fixed::<6>()),
1563                        Value::product(
1564                            Value::none(Final::two_two_n_fixed::<5>()),
1565                            Value::product(
1566                                Value::none(Final::two_two_n_fixed::<4>()),
1567                                Value::some(Value::u8(b'n')),
1568                            ),
1569                        ),
1570                    ),
1571                ),
1572            ),
1573        );
1574    }
1575}
1576
1577#[cfg(bench)]
1578mod benches {
1579    use super::*;
1580
1581    use crate::bit_encoding::{BitCollector as _, BitIter};
1582
1583    use test::{black_box, Bencher};
1584
1585    // Create values directly
1586    #[bench]
1587    fn bench_value_create_u64(bh: &mut Bencher) {
1588        bh.iter(|| black_box(Value::u64(0xff00_00ff_ff00_00ff)))
1589    }
1590
1591    #[bench]
1592    fn bench_value_create_u2048(bh: &mut Bencher) {
1593        bh.iter(|| black_box(Value::from_byte_array([0xcd; 2048])));
1594    }
1595
1596    #[bench]
1597    fn bench_value_create_deep_some(bh: &mut Bencher) {
1598        bh.iter(|| {
1599            let mut kilo = Value::from_byte_array([0xab; 1024]);
1600            for _ in 0..1000 {
1601                kilo = Value::some(kilo.shallow_clone());
1602            }
1603            black_box(kilo)
1604        });
1605    }
1606
1607    #[bench]
1608    fn bench_value_create_64k(bh: &mut Bencher) {
1609        bh.iter(|| {
1610            let mut kilo = Value::from_byte_array([0xab; 1024]);
1611            for _ in 0..5 {
1612                kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1613            }
1614            black_box(kilo)
1615        });
1616    }
1617
1618    #[bench]
1619    fn bench_value_create_512_256(bh: &mut Bencher) {
1620        bh.iter(|| {
1621            // This is a common "slow" pattern in my Elements fuzzer; it is a deeply
1622            // nested product of 2^512 x 2^256, which is not a "primitive numeric
1623            // type" and therefore cannot be quickly decoded from compact bits by
1624            // simply matching to pre-computed types.
1625            //
1626            // However, this type is a giant product of bits. Its compact encoding
1627            // is therefore equal to its padded encoding and we should be able to
1628            // quickly decode it.
1629            let mut s512_256 = Value::product(
1630                Value::from_byte_array([0x12; 64]),
1631                Value::from_byte_array([0x23; 32]),
1632            );
1633            for _ in 0..5 {
1634                s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1635            }
1636            black_box(s512_256);
1637        });
1638    }
1639
1640    // Create values from padded bits
1641    fn padded_bits(v: &Value) -> (Vec<u8>, &Final) {
1642        let (bits, _) = v.iter_padded().collect_bits();
1643        (bits, v.ty.as_ref())
1644    }
1645
1646    #[bench]
1647    fn bench_value_create_u64_padded(bh: &mut Bencher) {
1648        let v = Value::u64(0xff00_00ff_ff00_00ff);
1649        let (bits, ty) = padded_bits(&v);
1650        bh.iter(|| {
1651            black_box(Value::from_padded_bits(
1652                &mut BitIter::new(bits.iter().copied()),
1653                ty,
1654            ))
1655        })
1656    }
1657
1658    #[bench]
1659    fn bench_value_create_u2048_padded(bh: &mut Bencher) {
1660        let v = Value::from_byte_array([0xcd; 2048]);
1661        let (bits, ty) = padded_bits(&v);
1662        bh.iter(|| {
1663            black_box(Value::from_padded_bits(
1664                &mut BitIter::new(bits.iter().copied()),
1665                ty,
1666            ))
1667        })
1668    }
1669
1670    #[bench]
1671    fn bench_value_create_deep_some_padded(bh: &mut Bencher) {
1672        let mut kilo = Value::from_byte_array([0xab; 1024]);
1673        for _ in 0..1000 {
1674            kilo = Value::some(kilo.shallow_clone());
1675        }
1676        let (bits, ty) = padded_bits(&kilo);
1677        bh.iter(|| {
1678            black_box(Value::from_padded_bits(
1679                &mut BitIter::new(bits.iter().copied()),
1680                ty,
1681            ))
1682        })
1683    }
1684
1685    #[bench]
1686    fn bench_value_create_64k_padded(bh: &mut Bencher) {
1687        let mut kilo = Value::from_byte_array([0xab; 1024]);
1688        for _ in 0..5 {
1689            kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1690        }
1691        let (bits, ty) = padded_bits(&kilo);
1692        bh.iter(|| {
1693            black_box(Value::from_padded_bits(
1694                &mut BitIter::new(bits.iter().copied()),
1695                ty,
1696            ))
1697        })
1698    }
1699
1700    #[bench]
1701    fn bench_value_create_512_256_padded(bh: &mut Bencher) {
1702        // See comment in bench_value_create_512_256 about this value
1703        let mut s512_256 = Value::product(
1704            Value::from_byte_array([0x12; 64]),
1705            Value::from_byte_array([0x23; 32]),
1706        );
1707        for _ in 0..5 {
1708            s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1709        }
1710        let (bits, ty) = padded_bits(&s512_256);
1711        bh.iter(|| {
1712            black_box(Value::from_padded_bits(
1713                &mut BitIter::new(bits.iter().copied()),
1714                ty,
1715            ))
1716        })
1717    }
1718
1719    // Create values from compact bits
1720    fn compact_bits(v: &Value) -> (Vec<u8>, &Final) {
1721        let (bits, _) = v.iter_compact().collect_bits();
1722        (bits, v.ty.as_ref())
1723    }
1724
1725    #[bench]
1726    fn bench_value_create_u64_compact(bh: &mut Bencher) {
1727        let v = Value::u64(0xff00_00ff_ff00_00ff);
1728        let (bits, ty) = compact_bits(&v);
1729        bh.iter(|| {
1730            black_box(Value::from_compact_bits(
1731                &mut BitIter::new(bits.iter().copied()),
1732                ty,
1733            ))
1734        })
1735    }
1736
1737    #[bench]
1738    fn bench_value_create_u2048_compact(bh: &mut Bencher) {
1739        let v = Value::from_byte_array([0xcd; 2048]);
1740        let (bits, ty) = compact_bits(&v);
1741        bh.iter(|| {
1742            black_box(Value::from_compact_bits(
1743                &mut BitIter::new(bits.iter().copied()),
1744                ty,
1745            ))
1746        })
1747    }
1748
1749    #[bench]
1750    fn bench_value_create_deep_some_compact(bh: &mut Bencher) {
1751        let mut kilo = Value::from_byte_array([0xab; 1024]);
1752        for _ in 0..1000 {
1753            kilo = Value::some(kilo.shallow_clone());
1754        }
1755        let (bits, ty) = compact_bits(&kilo);
1756        bh.iter(|| {
1757            black_box(Value::from_compact_bits(
1758                &mut BitIter::new(bits.iter().copied()),
1759                ty,
1760            ))
1761        })
1762    }
1763
1764    #[bench]
1765    fn bench_value_create_64k_compact(bh: &mut Bencher) {
1766        let mut kilo = Value::from_byte_array([0xab; 1024]);
1767        for _ in 0..5 {
1768            kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1769        }
1770        let (bits, ty) = compact_bits(&kilo);
1771        bh.iter(|| {
1772            black_box(Value::from_compact_bits(
1773                &mut BitIter::new(bits.iter().copied()),
1774                ty,
1775            ))
1776        })
1777    }
1778
1779    #[bench]
1780    fn bench_value_create_512_256_compact(bh: &mut Bencher) {
1781        // See comment in bench_value_create_512_256 about this value
1782        let mut s512_256 = Value::product(
1783            Value::from_byte_array([0x12; 64]),
1784            Value::from_byte_array([0x23; 32]),
1785        );
1786        for _ in 0..5 {
1787            s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1788        }
1789        let (bits, ty) = compact_bits(&s512_256);
1790        bh.iter(|| {
1791            black_box(Value::from_compact_bits(
1792                &mut BitIter::new(bits.iter().copied()),
1793                ty,
1794            ))
1795        })
1796    }
1797
1798    // Display values
1799    #[bench]
1800    fn bench_value_display_u64(bh: &mut Bencher) {
1801        let v = Value::u64(0xff00_00ff_ff00_00ff);
1802        bh.iter(|| black_box(format!("{}", v)))
1803    }
1804
1805    #[bench]
1806    fn bench_value_display_u2024(bh: &mut Bencher) {
1807        let v = Value::from_byte_array([0xcd; 2048]);
1808        bh.iter(|| black_box(format!("{}", v)))
1809    }
1810
1811    #[bench]
1812    fn bench_value_display_deep_some(bh: &mut Bencher) {
1813        let mut kilo = Value::from_byte_array([0xab; 1024]);
1814        for _ in 0..1000 {
1815            kilo = Value::some(kilo.shallow_clone());
1816        }
1817        bh.iter(|| black_box(format!("{}", kilo)))
1818    }
1819
1820    #[bench]
1821    fn bench_value_display_64k(bh: &mut Bencher) {
1822        let mut kilo = Value::from_byte_array([0xab; 1024]);
1823        for _ in 0..5 {
1824            kilo = Value::product(kilo.shallow_clone(), kilo.shallow_clone());
1825        }
1826        bh.iter(|| black_box(format!("{}", kilo)))
1827    }
1828
1829    #[bench]
1830    fn bench_value_display_512_256(bh: &mut Bencher) {
1831        // See comment in bench_value_create_512_256 about this value
1832        let mut s512_256 = Value::product(
1833            Value::from_byte_array([0x12; 64]),
1834            Value::from_byte_array([0x23; 32]),
1835        );
1836        for _ in 0..5 {
1837            s512_256 = Value::product(s512_256.shallow_clone(), s512_256.shallow_clone());
1838        }
1839        bh.iter(|| black_box(format!("{}", s512_256)))
1840    }
1841
1842    // Display values
1843}