decaf377/ark_curve/
encoding.rs1#![allow(non_snake_case)]
2
3use core::convert::{TryFrom, TryInto};
4
5use ark_ec::twisted_edwards::TECurveConfig;
6use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, Write};
7
8use crate::ark_curve::{
9 constants::TWO, edwards::Decaf377EdwardsConfig, on_curve::OnCurve, EdwardsProjective, Element,
10};
11use crate::sign::Sign;
12use crate::{EncodingError, Fq};
13
14#[derive(Copy, Clone, Default, Eq, Ord, PartialOrd, PartialEq)]
15pub struct Encoding(pub [u8; 32]);
16
17impl core::fmt::Debug for Encoding {
18 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19 f.write_fmt(format_args!(
20 "decaf377::Encoding({})",
21 hex::encode(&self.0[..])
22 ))
23 }
24}
25
26impl Encoding {
27 #[deprecated(note = "please use `vartime_decompress` instead")]
28 pub fn decompress(&self) -> Result<Element, EncodingError> {
29 self.vartime_decompress()
30 }
31
32 pub fn vartime_decompress(&self) -> Result<Element, EncodingError> {
33 if self.0[31] >> 5 != 0u8 {
35 return Err(EncodingError::InvalidEncoding);
36 }
37
38 let D4: Fq = Decaf377EdwardsConfig::COEFF_D * Fq::from(4u32);
41
42 let s =
44 Fq::deserialize_compressed(&self.0[..]).map_err(|_| EncodingError::InvalidEncoding)?;
45 if s.is_negative() {
46 return Err(EncodingError::InvalidEncoding);
47 }
48
49 let ss = s.square();
51 let u_1 = Fq::ONE - ss;
52
53 let u_2 = u_1.square() - D4 * ss;
55
56 let (was_square, mut v) = Fq::sqrt_ratio_zeta(&Fq::ONE, &(u_2 * u_1.square()));
58 if !was_square {
59 return Err(EncodingError::InvalidEncoding);
60 }
61
62 let two_s_u_1 = *TWO * s * u_1;
64 let check = two_s_u_1 * v;
65 if check.is_negative() {
66 v = -v;
67 }
68
69 let x = two_s_u_1 * v.square() * u_2;
71 let y = (Fq::ONE + ss) * v * u_1;
72 let z = Fq::ONE;
73 let t = x * y;
74
75 debug_assert!(
76 EdwardsProjective::new(x, y, t, z).is_on_curve(),
77 "resulting point must be on the curve",
78 );
79
80 Ok(Element {
81 inner: EdwardsProjective::new(x, y, t, z),
82 })
83 }
84}
85
86impl Element {
87 pub fn negate(&self) -> Element {
88 Element { inner: -self.inner }
89 }
90
91 pub fn vartime_compress_to_field(&self) -> Fq {
92 let A_MINUS_D = Decaf377EdwardsConfig::COEFF_A - Decaf377EdwardsConfig::COEFF_D;
95 let p = &self.inner;
96
97 let u_1 = (p.x + p.t) * (p.x - p.t);
99
100 let (_always_square, v) = Fq::sqrt_ratio_zeta(&Fq::ONE, &(u_1 * A_MINUS_D * p.x.square()));
103
104 let u_2 = (v * u_1).abs();
106
107 let u_3 = u_2 * p.z - p.t;
109
110 let s = (A_MINUS_D * v * u_3 * p.x).abs();
112
113 s
114 }
115
116 pub fn vartime_compress(&self) -> Encoding {
117 let s = self.vartime_compress_to_field();
118
119 let mut bytes = [0u8; 32];
121 debug_assert_eq!(s.serialized_size(ark_serialize::Compress::Yes), 32);
122 s.serialize_compressed(&mut bytes[..])
123 .expect("serialization into array should be infallible");
124 bytes[31] &= 0b00011111;
126
127 Encoding(bytes)
128 }
129}
130
131impl From<&Element> for Encoding {
132 fn from(point: &Element) -> Self {
133 point.vartime_compress()
134 }
135}
136
137impl From<Element> for Encoding {
138 fn from(point: Element) -> Self {
139 point.vartime_compress()
140 }
141}
142
143impl CanonicalSerialize for Encoding {
144 fn serialized_size(&self, compress: ark_serialize::Compress) -> usize {
145 match compress {
146 ark_serialize::Compress::Yes => 32,
147 ark_serialize::Compress::No => unimplemented!(),
148 }
149 }
150
151 fn serialize_with_mode<W: Write>(
152 &self,
153 mut writer: W,
154 _mode: ark_serialize::Compress,
155 ) -> Result<(), ark_serialize::SerializationError> {
156 writer.write_all(&self.0[..])?;
157 Ok(())
158 }
159}
160
161impl CanonicalSerialize for Element {
162 fn serialized_size(&self, compress: ark_serialize::Compress) -> usize {
163 match compress {
164 ark_serialize::Compress::Yes => 32,
165 ark_serialize::Compress::No => unimplemented!(),
166 }
167 }
168
169 fn serialize_with_mode<W: Write>(
170 &self,
171 writer: W,
172 mode: ark_serialize::Compress,
173 ) -> Result<(), ark_serialize::SerializationError> {
174 self.vartime_compress().serialize_with_mode(writer, mode)
175 }
176}
177
178impl TryFrom<&[u8]> for Encoding {
179 type Error = EncodingError;
180
181 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
182 if bytes.len() == 32 {
183 let mut arr = [0u8; 32];
184 arr.copy_from_slice(&bytes[0..32]);
185 Ok(Encoding(arr))
186 } else {
187 Err(EncodingError::InvalidSliceLength)
188 }
189 }
190}
191
192impl From<[u8; 32]> for Encoding {
193 fn from(bytes: [u8; 32]) -> Encoding {
194 Encoding(bytes)
195 }
196}
197
198impl From<Encoding> for [u8; 32] {
199 fn from(enc: Encoding) -> [u8; 32] {
200 enc.0
201 }
202}
203
204impl TryFrom<&Encoding> for Element {
205 type Error = EncodingError;
206 fn try_from(bytes: &Encoding) -> Result<Self, Self::Error> {
207 bytes.vartime_decompress()
208 }
209}
210
211impl TryFrom<Encoding> for Element {
212 type Error = EncodingError;
213 fn try_from(bytes: Encoding) -> Result<Self, Self::Error> {
214 bytes.vartime_decompress()
215 }
216}
217
218impl TryFrom<&[u8]> for Element {
219 type Error = EncodingError;
220
221 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
222 let b: [u8; 32] = bytes
223 .try_into()
224 .map_err(|_| EncodingError::InvalidSliceLength)?;
225
226 Encoding(b).try_into()
227 }
228}
229
230impl TryFrom<[u8; 32]> for Element {
231 type Error = EncodingError;
232
233 fn try_from(bytes: [u8; 32]) -> Result<Self, Self::Error> {
234 let encoding = Encoding(bytes);
235 encoding.try_into()
236 }
237}
238
239impl From<Element> for [u8; 32] {
240 fn from(enc: Element) -> [u8; 32] {
241 enc.vartime_compress().0
242 }
243}
244
245impl ark_serialize::Valid for Encoding {
246 fn check(&self) -> Result<(), ark_serialize::SerializationError> {
247 Ok(())
250 }
251}
252
253impl CanonicalDeserialize for Encoding {
254 fn deserialize_with_mode<R: Read>(
255 mut reader: R,
256 compress: ark_serialize::Compress,
257 validate: ark_serialize::Validate,
258 ) -> Result<Self, ark_serialize::SerializationError> {
259 match compress {
260 ark_serialize::Compress::Yes => (),
261 ark_serialize::Compress::No => unimplemented!(),
262 }
263 match validate {
264 ark_serialize::Validate::Yes => (),
265 ark_serialize::Validate::No => unimplemented!(),
266 }
267 let mut bytes = [0u8; 32];
268 reader.read_exact(&mut bytes[..])?;
269 Ok(Self(bytes))
270 }
271}
272
273impl CanonicalDeserialize for Element {
274 fn deserialize_with_mode<R: Read>(
275 reader: R,
276 compress: ark_serialize::Compress,
277 validate: ark_serialize::Validate,
278 ) -> Result<Self, ark_serialize::SerializationError> {
279 match compress {
280 ark_serialize::Compress::Yes => (),
281 ark_serialize::Compress::No => unimplemented!(),
282 }
283 match validate {
284 ark_serialize::Validate::Yes => (),
285 ark_serialize::Validate::No => unimplemented!(),
286 }
287 let bytes = Encoding::deserialize_compressed(reader)?;
288 bytes
289 .try_into()
290 .map_err(|_| ark_serialize::SerializationError::InvalidData)
291 }
292}