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 }