/ circuit / types / group / src / helpers / from_bits.rs
from_bits.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // This file is part of the AlphaVM library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  use super::*;
 17  
 18  impl<E: Environment> FromBits for Group<E> {
 19      type Boolean = Boolean<E>;
 20  
 21      /// Initializes a new group element from the x-coordinate as a list of little-endian bits *without* trailing zeros.
 22      fn from_bits_le(bits_le: &[Self::Boolean]) -> Self {
 23          // Derive the x-coordinate for the affine group element.
 24          let x = Field::from_bits_le(bits_le);
 25          // Recover the y-coordinate and return the affine group element.
 26          Self::from_x_coordinate(x)
 27      }
 28  
 29      /// Initializes a new group element from the x-coordinate as a list of big-endian bits *without* leading zeros.
 30      fn from_bits_be(bits_be: &[Self::Boolean]) -> Self {
 31          // Derive the x-coordinate for the affine group element.
 32          let x = Field::from_bits_be(bits_be);
 33          // Recover the y-coordinate and return the affine group element.
 34          Self::from_x_coordinate(x)
 35      }
 36  }
 37  
 38  #[cfg(test)]
 39  mod tests {
 40      use super::*;
 41      use alphavm_circuit_environment::Circuit;
 42  
 43      const ITERATIONS: u64 = 100;
 44  
 45      fn check_from_bits_le(mode: Mode, num_constants: u64, num_public: u64, num_private: u64, num_constraints: u64) {
 46          let mut rng = TestRng::default();
 47  
 48          for i in 0..ITERATIONS {
 49              // Sample a random element.
 50              let expected = Uniform::rand(&mut rng);
 51              let candidate = Group::<Circuit>::new(mode, expected).to_bits_le();
 52  
 53              Circuit::scope(format!("{mode} {i}"), || {
 54                  let candidate = Group::<Circuit>::from_bits_le(&candidate);
 55                  assert_eq!(expected, candidate.eject_value());
 56                  assert_scope!(num_constants, num_public, num_private, num_constraints);
 57              });
 58              Circuit::reset();
 59          }
 60      }
 61  
 62      fn check_from_bits_be(mode: Mode, num_constants: u64, num_public: u64, num_private: u64, num_constraints: u64) {
 63          let mut rng = TestRng::default();
 64  
 65          for i in 0..ITERATIONS {
 66              // Sample a random element.
 67              let expected = Uniform::rand(&mut rng);
 68              let candidate = Group::<Circuit>::new(mode, expected).to_bits_be();
 69  
 70              Circuit::scope(format!("{mode} {i}"), || {
 71                  let candidate = Group::<Circuit>::from_bits_be(&candidate);
 72                  assert_eq!(expected, candidate.eject_value());
 73                  assert_scope!(num_constants, num_public, num_private, num_constraints);
 74              });
 75              Circuit::reset();
 76          }
 77      }
 78  
 79      #[test]
 80      fn test_from_bits_le_constant() {
 81          check_from_bits_le(Mode::Constant, 9, 0, 0, 0);
 82      }
 83  
 84      #[test]
 85      fn test_from_bits_le_public() {
 86          check_from_bits_le(Mode::Public, 4, 0, 265, 266);
 87      }
 88  
 89      #[test]
 90      fn test_from_bits_le_private() {
 91          check_from_bits_le(Mode::Private, 4, 0, 265, 266);
 92      }
 93  
 94      #[test]
 95      fn test_from_bits_be_constant() {
 96          check_from_bits_be(Mode::Constant, 9, 0, 0, 0);
 97      }
 98  
 99      #[test]
100      fn test_from_bits_be_public() {
101          check_from_bits_be(Mode::Public, 4, 0, 265, 266);
102      }
103  
104      #[test]
105      fn test_from_bits_be_private() {
106          check_from_bits_be(Mode::Private, 4, 0, 265, 266);
107      }
108  }