arnaucube
arnaucube/ark-curves-cherry-pickedPublic Self-hosted repository
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}