/ fields / src / to_field_vec.rs
to_field_vec.rs
  1  // Copyright (c) 2025-2026 ACDC Network
  2  // This file is part of the alphavm library.
  3  //
  4  // Alpha Chain | Delta Chain Protocol
  5  // International Monetary Graphite.
  6  //
  7  // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com).
  8  // They built world-class ZK infrastructure. We installed the EASY button.
  9  // Their cryptography: elegant. Our modifications: bureaucracy-compatible.
 10  // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours.
 11  //
 12  // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
 13  // All modifications and new work: CC0 1.0 Universal Public Domain Dedication.
 14  // No rights reserved. No permission required. No warranty. No refunds.
 15  //
 16  // https://creativecommons.org/publicdomain/zero/1.0/
 17  // SPDX-License-Identifier: CC0-1.0
 18  
 19  use crate::{ConstraintFieldError, Field, Fp2, Fp2Parameters, PrimeField, ToConstraintField};
 20  use alphavm_utilities::FromBits;
 21  
 22  impl<F: Field> ToConstraintField<F> for () {
 23      #[inline]
 24      fn to_field_elements(&self) -> Result<Vec<F>, ConstraintFieldError> {
 25          Ok(Vec::new())
 26      }
 27  }
 28  
 29  impl<F: Field> ToConstraintField<F> for bool {
 30      fn to_field_elements(&self) -> Result<Vec<F>, ConstraintFieldError> {
 31          if *self {
 32              Ok(vec![F::one()])
 33          } else {
 34              Ok(vec![F::zero()])
 35          }
 36      }
 37  }
 38  
 39  impl<F: PrimeField> ToConstraintField<F> for F {
 40      fn to_field_elements(&self) -> Result<Vec<F>, ConstraintFieldError> {
 41          Ok(vec![*self])
 42      }
 43  }
 44  
 45  impl<F: Field> ToConstraintField<F> for [F] {
 46      #[inline]
 47      fn to_field_elements(&self) -> Result<Vec<F>, ConstraintFieldError> {
 48          Ok(self.to_vec())
 49      }
 50  }
 51  
 52  impl<F: Field> ToConstraintField<F> for Vec<F> {
 53      #[inline]
 54      fn to_field_elements(&self) -> Result<Vec<F>, ConstraintFieldError> {
 55          Ok(self.to_vec())
 56      }
 57  }
 58  
 59  impl<P: Fp2Parameters> ToConstraintField<P::Fp> for Fp2<P> {
 60      #[inline]
 61      fn to_field_elements(&self) -> Result<Vec<P::Fp>, ConstraintFieldError> {
 62          let mut c0 = self.c0.to_field_elements()?;
 63          let c1 = self.c1.to_field_elements()?;
 64          c0.extend_from_slice(&c1);
 65          Ok(c0)
 66      }
 67  }
 68  
 69  impl<F: PrimeField> ToConstraintField<F> for [bool] {
 70      #[inline]
 71      fn to_field_elements(&self) -> Result<Vec<F>, ConstraintFieldError> {
 72          self.chunks(F::size_in_data_bits())
 73              .map(|chunk| {
 74                  F::from_bigint(F::BigInteger::from_bits_le(chunk)?)
 75                      .ok_or(ConstraintFieldError::Message("Invalid data bits for constraint field"))
 76              })
 77              .collect::<Result<Vec<F>, _>>()
 78      }
 79  }
 80  
 81  impl<F: PrimeField, const NUM_BITS: usize> ToConstraintField<F> for [bool; NUM_BITS] {
 82      #[inline]
 83      fn to_field_elements(&self) -> Result<Vec<F>, ConstraintFieldError> {
 84          self.as_ref().to_field_elements()
 85      }
 86  }
 87  
 88  impl<F: PrimeField> ToConstraintField<F> for [u8] {
 89      #[inline]
 90      fn to_field_elements(&self) -> Result<Vec<F>, ConstraintFieldError> {
 91          // Derive the field size in bytes, floored to be conservative.
 92          let floored_field_size_in_bytes = F::size_in_data_bits() / 8;
 93          let next_power_of_two = floored_field_size_in_bytes
 94              .checked_next_power_of_two()
 95              .ok_or(ConstraintFieldError::Message("Field size is too large"))?;
 96  
 97          // Pack the bytes into field elements.
 98          Ok(self
 99              .chunks(floored_field_size_in_bytes)
100              .map(|chunk| {
101                  // Before packing, pad the chunk to the next power of two.
102                  let mut chunk_vec = vec![0u8; next_power_of_two];
103                  chunk_vec[..chunk.len()].copy_from_slice(chunk);
104                  F::read_le(&*chunk_vec)
105              })
106              .collect::<Result<Vec<_>, _>>()?)
107      }
108  }
109  
110  impl<F: PrimeField, const NUM_BYTES: usize> ToConstraintField<F> for [u8; NUM_BYTES] {
111      #[inline]
112      fn to_field_elements(&self) -> Result<Vec<F>, ConstraintFieldError> {
113          self.as_ref().to_field_elements()
114      }
115  }