snarkvm_circuit_account/signature/helpers/
from_bits.rs1use super::*;
17
18#[cfg(feature = "console")]
19impl<A: Aleo> FromBits for Signature<A> {
20 type Boolean = Boolean<A>;
21
22 fn from_bits_le(bits_le: &[Self::Boolean]) -> Self {
24 let scalar_size_in_bits = console::Scalar::<A::Network>::size_in_bits();
25 let compute_key_size_in_bits = console::ComputeKey::<A::Network>::size_in_bits();
26
27 let (challenge_start, challenge_end) = (0, scalar_size_in_bits);
28 let (response_start, response_end) = (challenge_end, challenge_end + scalar_size_in_bits);
29 let (compute_key_start, compute_key_end) = (response_end, response_end + compute_key_size_in_bits);
30
31 let Some(challenge_bits) = bits_le.get(challenge_start..challenge_end) else {
32 A::halt("Unable to recover the signature challenge from (LE) bits")
33 };
34 let Some(response_bits) = bits_le.get(response_start..response_end) else {
35 A::halt("Unable to recover the signature response from (LE) bits")
36 };
37 let Some(compute_key_bits) = bits_le.get(compute_key_start..compute_key_end) else {
38 A::halt("Unable to recover the signature compute key from (LE) bits")
39 };
40
41 Self {
42 challenge: Scalar::from_bits_le(challenge_bits),
43 response: Scalar::from_bits_le(response_bits),
44 compute_key: ComputeKey::from_bits_le(compute_key_bits),
45 }
46 }
47
48 fn from_bits_be(bits_be: &[Self::Boolean]) -> Self {
50 let scalar_size_in_bits = console::Scalar::<A::Network>::size_in_bits();
51 let compute_key_size_in_bits = console::ComputeKey::<A::Network>::size_in_bits();
52
53 let (challenge_start, challenge_end) = (0, scalar_size_in_bits);
54 let (response_start, response_end) = (challenge_end, challenge_end + scalar_size_in_bits);
55 let (compute_key_start, compute_key_end) = (response_end, response_end + compute_key_size_in_bits);
56
57 let Some(challenge_bits) = bits_be.get(challenge_start..challenge_end) else {
58 A::halt("Unable to recover the signature challenge from (BE) bits")
59 };
60 let Some(response_bits) = bits_be.get(response_start..response_end) else {
61 A::halt("Unable to recover the signature response from (BE) bits")
62 };
63 let Some(compute_key_bits) = bits_be.get(compute_key_start..compute_key_end) else {
64 A::halt("Unable to recover the signature compute key from (BE) bits")
65 };
66
67 Self {
68 challenge: Scalar::from_bits_be(challenge_bits),
69 response: Scalar::from_bits_be(response_bits),
70 compute_key: ComputeKey::from_bits_be(compute_key_bits),
71 }
72 }
73}
74
75#[cfg(all(test, feature = "console"))]
76mod tests {
77 use super::*;
78 use crate::Circuit;
79 use snarkvm_circuit_network::AleoV0;
80 use snarkvm_utilities::TestRng;
81
82 type CurrentAleo = AleoV0;
83
84 const ITERATIONS: u64 = 100;
85
86 fn check_from_bits_le(mode: Mode, num_constants: u64, num_public: u64, num_private: u64, num_constraints: u64) {
87 let rng = &mut TestRng::default();
88
89 for i in 0..ITERATIONS {
90 let expected = crate::helpers::generate_signature(i, rng);
92 let candidate = Signature::<CurrentAleo>::new(mode, expected).to_bits_le();
93
94 CurrentAleo::scope(format!("{mode} {i}"), || {
95 let candidate = Signature::<CurrentAleo>::from_bits_le(&candidate);
96 assert_eq!(expected, candidate.eject_value());
97 assert_scope!(num_constants, num_public, num_private, num_constraints);
98 });
99 CurrentAleo::reset();
100 }
101 }
102
103 fn check_from_bits_be(mode: Mode, num_constants: u64, num_public: u64, num_private: u64, num_constraints: u64) {
104 let rng = &mut TestRng::default();
105
106 for i in 0..ITERATIONS {
107 let expected = crate::helpers::generate_signature(i, rng);
109 let candidate = Signature::<CurrentAleo>::new(mode, expected).to_bits_be();
110
111 CurrentAleo::scope(format!("{mode} {i}"), || {
112 let candidate = Signature::<CurrentAleo>::from_bits_be(&candidate);
113 assert_eq!(expected, candidate.eject_value());
114 assert_scope!(num_constants, num_public, num_private, num_constraints);
115 });
116 CurrentAleo::reset();
117 }
118 }
119
120 #[test]
121 fn test_from_bits_le_constant() {
122 check_from_bits_le(Mode::Constant, 272, 0, 0, 0);
123 }
124
125 #[test]
126 fn test_from_bits_le_public() {
127 check_from_bits_le(Mode::Public, 9, 0, 1875, 1881);
128 }
129
130 #[test]
131 fn test_from_bits_le_private() {
132 check_from_bits_le(Mode::Private, 9, 0, 1875, 1881);
133 }
134
135 #[test]
136 fn test_from_bits_be_constant() {
137 check_from_bits_be(Mode::Constant, 272, 0, 0, 0);
138 }
139
140 #[test]
141 fn test_from_bits_be_public() {
142 check_from_bits_be(Mode::Public, 9, 0, 1875, 1881);
143 }
144
145 #[test]
146 fn test_from_bits_be_private() {
147 check_from_bits_be(Mode::Private, 9, 0, 1875, 1881);
148 }
149}