ark-curves-cherry-picked/bls12_381/src/curves/util.rs
bls12_381/src/curves/util.rsRaw
1use ark_ec::{short_weierstrass::Affine, AffineRepr};
2use ark_ff::{BigInteger384, PrimeField};
3use ark_serialize::SerializationError;
4
5use crate::{
6 g1::Parameters as G1Parameters, g2::Parameters as G2Parameters, Fq, Fq2, G1Affine, G2Affine,
7};
8
9pub const G1_SERIALIZED_SIZE: usize = 48;
10pub const G2_SERIALIZED_SIZE: usize = 96;
11
12pub struct EncodingFlags {
13 pub is_compressed: bool,
14 pub is_infinity: bool,
15 pub is_lexographically_largest: bool,
16}
17
18impl EncodingFlags {
19 pub fn get_flags(bytes: &[u8]) -> Self {
20 let compression_flag_set = (bytes[0] >> 7) & 1;
21 let infinity_flag_set = (bytes[0] >> 6) & 1;
22 let sort_flag_set = (bytes[0] >> 5) & 1;
23
24 Self {
25 is_compressed: compression_flag_set == 1,
26 is_infinity: infinity_flag_set == 1,
27 is_lexographically_largest: sort_flag_set == 1,
28 }
29 }
30 pub fn encode_flags(&self, bytes: &mut [u8]) {
31 if self.is_compressed {
32 bytes[0] |= 1 << 7;
33 }
34
35 if self.is_infinity {
36 bytes[0] |= 1 << 6;
37 }
38
39 if self.is_compressed && !self.is_infinity && self.is_lexographically_largest {
40 bytes[0] |= 1 << 5;
41 }
42 }
43}
44
45pub(crate) fn deserialize_fq(bytes: [u8; 48]) -> Option<Fq> {
46 let mut tmp = BigInteger384::new([0, 0, 0, 0, 0, 0]);
47
48 // Note: The following unwraps are if the compiler cannot convert
49 // the byte slice into [u8;8], we know this is infallible since we
50 // are providing the indices at compile time and bytes has a fixed size
51 tmp.0[5] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap());
52 tmp.0[4] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap());
53 tmp.0[3] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap());
54 tmp.0[2] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap());
55 tmp.0[1] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[32..40]).unwrap());
56 tmp.0[0] = u64::from_be_bytes(<[u8; 8]>::try_from(&bytes[40..48]).unwrap());
57
58 Fq::from_bigint(tmp)
59}
60
61pub(crate) fn serialize_fq(field: Fq) -> [u8; 48] {
62 let mut result = [0u8; 48];
63
64 let rep = field.into_bigint();
65
66 result[0..8].copy_from_slice(&rep.0[5].to_be_bytes());
67 result[8..16].copy_from_slice(&rep.0[4].to_be_bytes());
68 result[16..24].copy_from_slice(&rep.0[3].to_be_bytes());
69 result[24..32].copy_from_slice(&rep.0[2].to_be_bytes());
70 result[32..40].copy_from_slice(&rep.0[1].to_be_bytes());
71 result[40..48].copy_from_slice(&rep.0[0].to_be_bytes());
72
73 result
74}
75
76pub(crate) fn read_fq_with_offset(
77 bytes: &[u8],
78 offset: usize,
79 mask: bool,
80) -> Result<Fq, ark_serialize::SerializationError> {
81 let mut tmp = [0; G1_SERIALIZED_SIZE];
82 // read `G1_SERIALIZED_SIZE` bytes
83 tmp.copy_from_slice(&bytes[offset * G1_SERIALIZED_SIZE..G1_SERIALIZED_SIZE * (offset + 1)]);
84
85 if mask {
86 // Mask away the flag bits
87 tmp[0] &= 0b0001_1111;
88 }
89 deserialize_fq(tmp).ok_or(SerializationError::InvalidData)
90}
91
92pub(crate) fn read_g1_compressed<R: ark_serialize::Read>(
93 mut reader: R,
94) -> Result<Affine<G1Parameters>, ark_serialize::SerializationError> {
95 let mut bytes = [0u8; G1_SERIALIZED_SIZE];
96 reader
97 .read_exact(&mut bytes)
98 .ok()
99 .ok_or(SerializationError::InvalidData)?;
100
101 // Obtain the three flags from the start of the byte sequence
102 let flags = EncodingFlags::get_flags(&bytes[..]);
103
104 // we expect to be deserializing a compressed point
105 if !flags.is_compressed {
106 return Err(SerializationError::UnexpectedFlags);
107 }
108
109 if flags.is_infinity {
110 return Ok(G1Affine::zero());
111 }
112
113 // Attempt to obtain the x-coordinate
114 let x = read_fq_with_offset(&bytes, 0, true)?;
115
116 let p = G1Affine::get_point_from_x_unchecked(x, flags.is_lexographically_largest)
117 .ok_or(SerializationError::InvalidData)?;
118
119 Ok(p)
120}
121
122pub(crate) fn read_g1_uncompressed<R: ark_serialize::Read>(
123 mut reader: R,
124) -> Result<Affine<G1Parameters>, ark_serialize::SerializationError> {
125 let mut bytes = [0u8; 2 * G1_SERIALIZED_SIZE];
126 reader
127 .read_exact(&mut bytes)
128 .map_err(|_| SerializationError::InvalidData)?;
129
130 // Obtain the three flags from the start of the byte sequence
131 let flags = EncodingFlags::get_flags(&bytes[..]);
132
133 // we expect to be deserializing an uncompressed point
134 if flags.is_compressed {
135 return Err(SerializationError::UnexpectedFlags);
136 }
137
138 if flags.is_infinity {
139 return Ok(G1Affine::zero());
140 }
141
142 // Attempt to obtain the x-coordinate
143 let x = read_fq_with_offset(&bytes, 0, true)?;
144 // Attempt to obtain the y-coordinate
145 let y = read_fq_with_offset(&bytes, 1, false)?;
146
147 let p = G1Affine::new_unchecked(x, y);
148
149 Ok(p)
150}
151
152pub(crate) fn read_g2_compressed<R: ark_serialize::Read>(
153 mut reader: R,
154) -> Result<Affine<G2Parameters>, ark_serialize::SerializationError> {
155 let mut bytes = [0u8; G2_SERIALIZED_SIZE];
156 reader
157 .read_exact(&mut bytes)
158 .map_err(|_| SerializationError::InvalidData)?;
159
160 // Obtain the three flags from the start of the byte sequence
161 let flags = EncodingFlags::get_flags(&bytes);
162
163 // we expect to be deserializing a compressed point
164 if !flags.is_compressed {
165 return Err(SerializationError::UnexpectedFlags);
166 }
167
168 if flags.is_infinity {
169 return Ok(G2Affine::zero());
170 }
171
172 // Attempt to obtain the x-coordinate
173 let xc1 = read_fq_with_offset(&bytes, 0, true)?;
174 let xc0 = read_fq_with_offset(&bytes, 1, false)?;
175
176 let x = Fq2::new(xc0, xc1);
177
178 let p = G2Affine::get_point_from_x_unchecked(x, flags.is_lexographically_largest)
179 .ok_or(SerializationError::InvalidData)?;
180
181 Ok(p)
182}
183
184pub(crate) fn read_g2_uncompressed<R: ark_serialize::Read>(
185 mut reader: R,
186) -> Result<Affine<G2Parameters>, ark_serialize::SerializationError> {
187 let mut bytes = [0u8; 2 * G2_SERIALIZED_SIZE];
188 reader
189 .read_exact(&mut bytes)
190 .map_err(|_| SerializationError::InvalidData)?;
191
192 // Obtain the three flags from the start of the byte sequence
193 let flags = EncodingFlags::get_flags(&bytes);
194
195 // we expect to be deserializing an uncompressed point
196 if flags.is_compressed {
197 return Err(SerializationError::UnexpectedFlags);
198 }
199
200 if flags.is_infinity {
201 return Ok(G2Affine::zero());
202 }
203
204 // Attempt to obtain the x-coordinate
205 let xc1 = read_fq_with_offset(&bytes, 0, true)?;
206 let xc0 = read_fq_with_offset(&bytes, 1, false)?;
207 let x = Fq2::new(xc0, xc1);
208
209 // Attempt to obtain the y-coordinate
210 let yc1 = read_fq_with_offset(&bytes, 2, false)?;
211 let yc0 = read_fq_with_offset(&bytes, 3, false)?;
212 let y = Fq2::new(yc0, yc1);
213
214 let p = G2Affine::new_unchecked(x, y);
215
216 Ok(p)
217}