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 }