snarkvm_console_types_scalar/
from_bits.rs1use super::*;
17
18impl<E: Environment> FromBits for Scalar<E> {
19 fn from_bits_le(bits_le: &[bool]) -> Result<Self> {
23 let size_in_data_bits = Scalar::<E>::size_in_data_bits();
25 let size_in_bits = Scalar::<E>::size_in_bits();
26
27 let num_bits = bits_le.len();
29 if num_bits > size_in_bits {
30 let should_be_zero = bits_le[size_in_bits..].iter().fold(false, |acc, bit| acc | bit);
32 ensure!(!should_be_zero, "The excess bits are not zero.");
34 }
35
36 if num_bits > size_in_data_bits {
38 let modulus = E::Scalar::modulus();
40
41 let scalar = E::BigInteger::from_bits_le(&bits_le[..size_in_bits])?;
45
46 ensure!(scalar < modulus, "The scalar is greater than or equal to the modulus.");
48
49 Ok(Scalar { scalar: E::Scalar::from_bigint(scalar).ok_or_else(|| anyhow!("Invalid scalar from bits"))? })
51 } else {
52 let mut sanitized_bits = vec![false; size_in_bits];
54 sanitized_bits[..num_bits].copy_from_slice(bits_le);
57
58 let scalar = E::Scalar::from_bigint(E::BigInteger::from_bits_le(&sanitized_bits)?)
60 .ok_or_else(|| anyhow!("Invalid scalar from bits"))?;
61
62 Ok(Scalar { scalar })
64 }
65 }
66
67 fn from_bits_be(bits_be: &[bool]) -> Result<Self> {
69 let mut bits_le = bits_be.to_vec();
72 bits_le.reverse();
73
74 Self::from_bits_le(&bits_le)
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use snarkvm_console_network_environment::Console;
82
83 type CurrentEnvironment = Console;
84
85 const ITERATIONS: usize = 100;
86
87 fn check_from_bits_le() -> Result<()> {
88 let mut rng = TestRng::default();
89
90 for i in 0..ITERATIONS {
91 let expected: Scalar<CurrentEnvironment> = Uniform::rand(&mut rng);
93 let given_bits = expected.to_bits_le();
94 assert_eq!(Scalar::<CurrentEnvironment>::size_in_bits(), given_bits.len());
95
96 let candidate = Scalar::<CurrentEnvironment>::from_bits_le(&given_bits)?;
97 assert_eq!(expected, candidate);
98
99 let candidate = [given_bits, vec![false; i]].concat();
101
102 let candidate = Scalar::<CurrentEnvironment>::from_bits_le(&candidate)?;
103 assert_eq!(expected, candidate);
104 assert_eq!(Scalar::<CurrentEnvironment>::size_in_bits(), candidate.to_bits_le().len());
105 }
106 Ok(())
107 }
108
109 fn check_from_bits_be() -> Result<()> {
110 let mut rng = TestRng::default();
111
112 for i in 0..ITERATIONS {
113 let expected: Scalar<CurrentEnvironment> = Uniform::rand(&mut rng);
115 let given_bits = expected.to_bits_be();
116 assert_eq!(Scalar::<CurrentEnvironment>::size_in_bits(), given_bits.len());
117
118 let candidate = Scalar::<CurrentEnvironment>::from_bits_be(&given_bits)?;
119 assert_eq!(expected, candidate);
120
121 let candidate = [vec![false; i], given_bits].concat();
123
124 let candidate = Scalar::<CurrentEnvironment>::from_bits_be(&candidate)?;
125 assert_eq!(expected, candidate);
126 assert_eq!(Scalar::<CurrentEnvironment>::size_in_bits(), candidate.to_bits_be().len());
127 }
128 Ok(())
129 }
130
131 #[test]
132 fn test_from_bits_le() -> Result<()> {
133 check_from_bits_le()
134 }
135
136 #[test]
137 fn test_from_bits_be() -> Result<()> {
138 check_from_bits_be()
139 }
140}