]> git.proxmox.com Git - rustc.git/blob - vendor/der/src/asn1/real.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / vendor / der / src / asn1 / real.rs
1 //! ASN.1 `REAL` support.
2
3 // TODO(tarcieri): checked arithmetic
4 #![allow(
5 clippy::cast_lossless,
6 clippy::cast_sign_loss,
7 clippy::integer_arithmetic
8 )]
9
10 use crate::{
11 str_slice::StrSlice, ByteSlice, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader,
12 Result, Tag, Writer,
13 };
14
15 use super::integer::uint::strip_leading_zeroes;
16
17 #[cfg_attr(docsrs, doc(cfg(feature = "real")))]
18 impl<'a> DecodeValue<'a> for f64 {
19 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
20 let bytes = ByteSlice::decode_value(reader, header)?.as_slice();
21
22 if header.length == Length::ZERO {
23 Ok(0.0)
24 } else if is_nth_bit_one::<7>(bytes) {
25 // Binary encoding from section 8.5.7 applies
26 let sign: u64 = if is_nth_bit_one::<6>(bytes) { 1 } else { 0 };
27
28 // Section 8.5.7.2: Check the base -- the DER specs say that only base 2 should be supported in DER
29 let base = mnth_bits_to_u8::<5, 4>(bytes);
30
31 if base != 0 {
32 // Real related error: base is not DER compliant (base encoded in enum)
33 return Err(Tag::Real.value_error());
34 }
35
36 // Section 8.5.7.3
37 let scaling_factor = mnth_bits_to_u8::<3, 2>(bytes);
38
39 // Section 8.5.7.4
40 let mantissa_start;
41 let exponent = match mnth_bits_to_u8::<1, 0>(bytes) {
42 0 => {
43 mantissa_start = 2;
44 let ebytes = (i16::from_be_bytes([0x0, bytes[1]])).to_be_bytes();
45 u64::from_be_bytes([0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ebytes[0], ebytes[1]])
46 }
47 1 => {
48 mantissa_start = 3;
49 let ebytes = (i16::from_be_bytes([bytes[1], bytes[2]])).to_be_bytes();
50 u64::from_be_bytes([0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ebytes[0], ebytes[1]])
51 }
52 _ => {
53 // Real related error: encoded exponent cannot be represented on an IEEE-754 double
54 return Err(Tag::Real.value_error());
55 }
56 };
57 // Section 8.5.7.5: Read the remaining bytes for the mantissa
58 let mut n_bytes = [0x0; 8];
59 for (pos, byte) in bytes[mantissa_start..].iter().rev().enumerate() {
60 n_bytes[7 - pos] = *byte;
61 }
62 let n = u64::from_be_bytes(n_bytes);
63 // Multiply byt 2^F corresponds to just a left shift
64 let mantissa = n << scaling_factor;
65 // Create the f64
66 Ok(encode_f64(sign, exponent, mantissa))
67 } else if is_nth_bit_one::<6>(bytes) {
68 // This either a special value, or it's the value minus zero is encoded, section 8.5.9 applies
69 match mnth_bits_to_u8::<1, 0>(bytes) {
70 0 => Ok(f64::INFINITY),
71 1 => Ok(f64::NEG_INFINITY),
72 2 => Ok(f64::NAN),
73 3 => Ok(-0.0_f64),
74 _ => Err(Tag::Real.value_error()),
75 }
76 } else {
77 let astr = StrSlice::from_bytes(&bytes[1..])?;
78 match astr.inner.parse::<f64>() {
79 Ok(val) => Ok(val),
80 // Real related error: encoding not supported or malformed
81 Err(_) => Err(Tag::Real.value_error()),
82 }
83 }
84 }
85 }
86
87 #[cfg_attr(docsrs, doc(cfg(feature = "real")))]
88 impl EncodeValue for f64 {
89 fn value_len(&self) -> Result<Length> {
90 if self.is_sign_positive() && (*self) < f64::MIN_POSITIVE {
91 // Zero: positive yet smaller than the minimum positive number
92 Ok(Length::ZERO)
93 } else if self.is_nan()
94 || self.is_infinite()
95 || (self.is_sign_negative() && -self < f64::MIN_POSITIVE)
96 {
97 // NaN, infinite (positive or negative), or negative zero (negative but its negative is less than the min positive number)
98 Ok(Length::ONE)
99 } else {
100 // The length is that of the first octets plus those needed for the exponent plus those needed for the mantissa
101 let (_sign, exponent, mantissa) = decode_f64(*self);
102
103 let exponent_len = if exponent == 0 {
104 // Section 8.5.7.4: there must be at least one octet for exponent encoding
105 // But, if the exponent is zero, it'll be skipped, so we make sure force it to 1
106 Length::ONE
107 } else {
108 let ebytes = exponent.to_be_bytes();
109 Length::try_from(strip_leading_zeroes(&ebytes).len())?
110 };
111
112 let mantissa_len = if mantissa == 0 {
113 Length::ONE
114 } else {
115 let mbytes = mantissa.to_be_bytes();
116 Length::try_from(strip_leading_zeroes(&mbytes).len())?
117 };
118
119 exponent_len + mantissa_len + Length::ONE
120 }
121 }
122
123 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
124 // Check if special value
125 // Encode zero first, if it's zero
126 // Special value from section 8.5.9 if non zero
127 if self.is_nan()
128 || self.is_infinite()
129 || (self.is_sign_negative() && -self < f64::MIN_POSITIVE)
130 || (self.is_sign_positive() && (*self) < f64::MIN_POSITIVE)
131 {
132 if self.is_sign_positive() && (*self) < f64::MIN_POSITIVE {
133 // Zero
134 return Ok(());
135 } else if self.is_nan() {
136 // Not a number
137 writer.write_byte(0b0100_0010)?;
138 } else if self.is_infinite() {
139 if self.is_sign_negative() {
140 // Negative infinity
141 writer.write_byte(0b0100_0001)?;
142 } else {
143 // Plus infinity
144 writer.write_byte(0b0100_0000)?;
145 }
146 } else {
147 // Minus zero
148 writer.write_byte(0b0100_0011)?;
149 }
150 } else {
151 // Always use binary encoding, set bit 8 to 1
152 let mut first_byte = 0b1000_0000;
153
154 if self.is_sign_negative() {
155 // Section 8.5.7.1: set bit 7 to 1 if negative
156 first_byte |= 0b0100_0000;
157 }
158
159 // Bits 6 and 5 are set to 0 to specify that binary encoding is used
160 //
161 // NOTE: the scaling factor is only used to align the implicit point of the mantissa.
162 // This is unnecessary in DER because the base is 2, and therefore necessarily aligned.
163 // Therefore, we do not modify the mantissa in anyway after this function call, which
164 // already adds the implicit one of the IEEE 754 representation.
165 let (_sign, exponent, mantissa) = decode_f64(*self);
166
167 // Encode the exponent as two's complement on 16 bits and remove the bias
168 let exponent_bytes = exponent.to_be_bytes();
169 let ebytes = strip_leading_zeroes(&exponent_bytes);
170
171 match ebytes.len() {
172 0 | 1 => {}
173 2 => first_byte |= 0b0000_0001,
174 3 => first_byte |= 0b0000_0010,
175 _ => {
176 // TODO: support multi octet exponent encoding?
177 return Err(Tag::Real.value_error());
178 }
179 }
180
181 writer.write_byte(first_byte)?;
182
183 // Encode both bytes or just the last one, handled by encode_bytes directly
184 // Rust already encodes the data as two's complement, so no further processing is needed
185 writer.write(ebytes)?;
186
187 // Now, encode the mantissa as unsigned binary number
188 let mantissa_bytes = mantissa.to_be_bytes();
189 let mbytes = strip_leading_zeroes(&mantissa_bytes);
190 writer.write(mbytes)?;
191 }
192
193 Ok(())
194 }
195 }
196
197 #[cfg_attr(docsrs, doc(cfg(feature = "real")))]
198 impl FixedTag for f64 {
199 const TAG: Tag = Tag::Real;
200 }
201
202 /// Is the N-th bit 1 in the first octet?
203 /// NOTE: this function is zero indexed
204 pub(crate) fn is_nth_bit_one<const N: usize>(bytes: &[u8]) -> bool {
205 if N < 8 {
206 bytes
207 .get(0)
208 .map(|byte| byte & (1 << N) != 0)
209 .unwrap_or(false)
210 } else {
211 false
212 }
213 }
214
215 /// Convert bits M, N into a u8, in the first octet only
216 pub(crate) fn mnth_bits_to_u8<const M: usize, const N: usize>(bytes: &[u8]) -> u8 {
217 let bit_m = is_nth_bit_one::<M>(bytes);
218 let bit_n = is_nth_bit_one::<N>(bytes);
219 (bit_m as u8) << 1 | bit_n as u8
220 }
221
222 /// Decode an f64 as its sign, exponent, and mantissa in u64 and in that order, using bit shifts and masks.
223 /// Note: this function **removes** the 1023 bias from the exponent and adds the implicit 1
224 #[allow(clippy::cast_possible_truncation)]
225 pub(crate) fn decode_f64(f: f64) -> (u64, u64, u64) {
226 let bits = f.to_bits();
227 let sign = bits >> 63;
228 let exponent = bits >> 52 & 0x7ff;
229 let exponent_bytes_no_bias = (exponent as i16 - 1023).to_be_bytes();
230 let exponent_no_bias = u64::from_be_bytes([
231 0x0,
232 0x0,
233 0x0,
234 0x0,
235 0x0,
236 0x0,
237 exponent_bytes_no_bias[0],
238 exponent_bytes_no_bias[1],
239 ]);
240 let mantissa = bits & 0xfffffffffffff;
241 (sign, exponent_no_bias, mantissa + 1)
242 }
243
244 /// Encode an f64 from its sign, exponent (**without** the 1023 bias), and (mantissa - 1) using bit shifts as received by ASN1
245 pub(crate) fn encode_f64(sign: u64, exponent: u64, mantissa: u64) -> f64 {
246 // Add the bias to the exponent
247 let exponent_with_bias =
248 (i16::from_be_bytes([exponent.to_be_bytes()[6], exponent.to_be_bytes()[7]]) + 1023) as u64;
249 let bits = sign << 63 | exponent_with_bias << 52 | (mantissa - 1);
250 f64::from_bits(bits)
251 }
252
253 #[cfg(test)]
254 mod tests {
255 use crate::{Decode, Encode};
256
257 #[test]
258 fn decode_subnormal() {
259 assert!(f64::from_der(&[0x09, 0x01, 0b0100_0010]).unwrap().is_nan());
260 let plus_infty = f64::from_der(&[0x09, 0x01, 0b0100_0000]).unwrap();
261 assert!(plus_infty.is_infinite() && plus_infty.is_sign_positive());
262 let neg_infty = f64::from_der(&[0x09, 0x01, 0b0100_0001]).unwrap();
263 assert!(neg_infty.is_infinite() && neg_infty.is_sign_negative());
264 let neg_zero = f64::from_der(&[0x09, 0x01, 0b0100_0011]).unwrap();
265 assert!(neg_zero.is_sign_negative() && neg_zero.abs() < f64::EPSILON);
266 }
267
268 #[test]
269 fn encode_subnormal() {
270 // All subnormal fit in three bytes
271 let mut buffer = [0u8; 3];
272 assert_eq!(
273 &[0x09, 0x01, 0b0100_0010],
274 f64::NAN.encode_to_slice(&mut buffer).unwrap()
275 );
276 assert_eq!(
277 &[0x09, 0x01, 0b0100_0000],
278 f64::INFINITY.encode_to_slice(&mut buffer).unwrap()
279 );
280 assert_eq!(
281 &[0x09, 0x01, 0b0100_0001],
282 f64::NEG_INFINITY.encode_to_slice(&mut buffer).unwrap()
283 );
284 assert_eq!(
285 &[0x09, 0x01, 0b0100_0011],
286 (-0.0_f64).encode_to_slice(&mut buffer).unwrap()
287 );
288 }
289
290 #[test]
291 fn encdec_normal() {
292 // The comments correspond to the decoded value from the ASN.1 playground when the bytes are inputed.
293 {
294 // rec1value R ::= 0
295 let val = 0.0;
296 let expected = &[0x09, 0x0];
297 let mut buffer = [0u8; 2];
298 let encoded = val.encode_to_slice(&mut buffer).unwrap();
299 assert_eq!(
300 expected, encoded,
301 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
302 val, encoded, expected
303 );
304 let decoded = f64::from_der(encoded).unwrap();
305 assert!(
306 (decoded - val).abs() < f64::EPSILON,
307 "wanted: {}\tgot: {}",
308 val,
309 decoded
310 );
311 }
312
313 {
314 // rec1value R ::= { mantissa 1, base 2, exponent 0 }
315 let val = 1.0;
316 let expected = &[0x09, 0x03, 0x80, 0x00, 0x01];
317 let mut buffer = [0u8; 5];
318 let encoded = val.encode_to_slice(&mut buffer).unwrap();
319 assert_eq!(
320 expected, encoded,
321 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
322 val, encoded, expected
323 );
324 let decoded = f64::from_der(encoded).unwrap();
325 assert!(
326 (decoded - val).abs() < f64::EPSILON,
327 "wanted: {}\tgot: {}",
328 val,
329 decoded
330 );
331 }
332
333 {
334 // rec1value R ::= { mantissa -1, base 2, exponent 0 }
335 let val = -1.0;
336 let expected = &[0x09, 0x03, 0xc0, 0x00, 0x01];
337 let mut buffer = [0u8; 5];
338 let encoded = val.encode_to_slice(&mut buffer).unwrap();
339 assert_eq!(
340 expected, encoded,
341 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
342 val, encoded, expected
343 );
344 let decoded = f64::from_der(encoded).unwrap();
345 assert!(
346 (decoded - val).abs() < f64::EPSILON,
347 "wanted: {}\tgot: {}",
348 val,
349 decoded
350 );
351 }
352
353 {
354 // rec1value R ::= { mantissa -1, base 2, exponent 1 }
355 let val = -1.0000000000000002;
356 let expected = &[0x09, 0x03, 0xc0, 0x00, 0x02];
357 let mut buffer = [0u8; 5];
358 let encoded = val.encode_to_slice(&mut buffer).unwrap();
359 assert_eq!(
360 expected, encoded,
361 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
362 val, encoded, expected
363 );
364 let decoded = f64::from_der(encoded).unwrap();
365 assert!(
366 (decoded - val).abs() < f64::EPSILON,
367 "wanted: {}\tgot: {}",
368 val,
369 decoded
370 );
371 }
372
373 {
374 // rec1value R ::= { mantissa 1, base 2, exponent -1022 }
375 // NOTE: f64::MIN_EXP == -1021 so the exponent decoded by ASN.1 is what we expect
376 let val = f64::MIN_POSITIVE;
377 let expected = &[0x09, 0x04, 0x81, 0xfc, 0x02, 0x01];
378 let mut buffer = [0u8; 7];
379 let encoded = val.encode_to_slice(&mut buffer).unwrap();
380 assert_eq!(
381 expected, encoded,
382 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
383 val, encoded, expected
384 );
385 let decoded = f64::from_der(encoded).unwrap();
386 assert!(
387 (decoded - val).abs() < f64::EPSILON,
388 "wanted: {}\tgot: {}",
389 val,
390 decoded
391 );
392 }
393
394 {
395 // rec4value R ::= { mantissa 1, base 2, exponent 3 }
396 let val = 1.0000000000000016;
397 let expected = &[0x09, 0x03, 0x80, 0x00, 0x08];
398 let mut buffer = [0u8; 5];
399 let encoded = val.encode_to_slice(&mut buffer).unwrap();
400 assert_eq!(
401 expected, encoded,
402 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
403 val, encoded, expected
404 );
405 let decoded = f64::from_der(encoded).unwrap();
406 assert!(
407 (decoded - val).abs() < f64::EPSILON,
408 "wanted: {}\tgot: {}",
409 val,
410 decoded
411 );
412 }
413
414 {
415 // rec5value R ::= { mantissa 4222124650659841, base 2, exponent 4 }
416 let val = 31.0;
417 let expected = &[
418 0x9, 0x9, 0x80, 0x04, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
419 ];
420 let mut buffer = [0u8; 11];
421 let encoded = val.encode_to_slice(&mut buffer).unwrap();
422 assert_eq!(
423 expected, encoded,
424 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
425 val, encoded, expected
426 );
427 let decoded = f64::from_der(encoded).unwrap();
428 assert!(
429 (decoded - val).abs() < f64::EPSILON,
430 "wanted: {}\tgot: {}",
431 val,
432 decoded
433 );
434 }
435 }
436
437 #[test]
438 fn encdec_irrationals() {
439 {
440 let val = core::f64::consts::PI;
441 let expected = &[
442 0x09, 0x09, 0x80, 0x01, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x19,
443 ];
444 let mut buffer = [0u8; 11];
445 let encoded = val.encode_to_slice(&mut buffer).unwrap();
446 assert_eq!(
447 expected, encoded,
448 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
449 val, encoded, expected
450 );
451 let decoded = f64::from_der(encoded).unwrap();
452 assert!(
453 (decoded - val).abs() < f64::EPSILON,
454 "wanted: {}\tgot: {}",
455 val,
456 decoded
457 );
458 }
459
460 {
461 let val = core::f64::consts::E;
462 let expected = &[
463 0x09, 0x09, 0x80, 0x01, 0x05, 0xbf, 0x0a, 0x8b, 0x14, 0x57, 0x6a,
464 ];
465 let mut buffer = [0u8; 12];
466 let encoded = val.encode_to_slice(&mut buffer).unwrap();
467 assert_eq!(
468 expected, encoded,
469 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
470 val, encoded, expected
471 );
472 let decoded = f64::from_der(encoded).unwrap();
473 assert!(
474 (decoded - val).abs() < f64::EPSILON,
475 "wanted: {}\tgot: {}",
476 val,
477 decoded
478 );
479 }
480 {
481 let val = core::f64::consts::LN_2;
482 let expected = &[
483 0x09, 0x0a, 0x81, 0xff, 0xff, 0x6, 0x2e, 0x42, 0xfe, 0xfa, 0x39, 0xf0,
484 ];
485 let mut buffer = [0u8; 12];
486 let encoded = val.encode_to_slice(&mut buffer).unwrap();
487 assert_eq!(
488 expected, encoded,
489 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
490 val, encoded, expected
491 );
492 let decoded = f64::from_der(encoded).unwrap();
493 assert!(
494 (decoded - val).abs() < f64::EPSILON,
495 "wanted: {}\tgot: {}",
496 val,
497 decoded
498 );
499 }
500 }
501
502 #[test]
503 fn encdec_reasonable_f64() {
504 // Tests the encoding and decoding of reals with some arbitrary numbers
505 {
506 // rec1value R ::= { mantissa 2414341043715239, base 2, exponent 21 }
507 let val = 3221417.1584163485;
508 let expected = &[
509 0x9, 0x9, 0x80, 0x15, 0x8, 0x93, 0xd4, 0x94, 0x46, 0xfc, 0xa7,
510 ];
511 let mut buffer = [0u8; 11];
512 let encoded = val.encode_to_slice(&mut buffer).unwrap();
513 assert_eq!(
514 expected, encoded,
515 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
516 val, encoded, expected
517 );
518 let decoded = f64::from_der(encoded).unwrap();
519 assert!(
520 (decoded - val).abs() < f64::EPSILON,
521 "wanted: {}\tgot: {}",
522 val,
523 decoded
524 );
525 }
526
527 {
528 // rec1value R ::= { mantissa 2671155248072715, base 2, exponent 23 }
529 let val = 13364022.365665454;
530 let expected = &[
531 0x09, 0x09, 0x80, 0x17, 0x09, 0x7d, 0x66, 0xcb, 0xb3, 0x88, 0x0b,
532 ];
533 let mut buffer = [0u8; 12];
534 let encoded = val.encode_to_slice(&mut buffer).unwrap();
535 assert_eq!(
536 expected, encoded,
537 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
538 val, encoded, expected
539 );
540 let decoded = f64::from_der(encoded).unwrap();
541 assert!(
542 (decoded - val).abs() < f64::EPSILON,
543 "wanted: {}\tgot: {}",
544 val,
545 decoded
546 );
547 }
548
549 {
550 // rec1value R ::= { mantissa -4386812962460287, base 2, exponent 14 }
551 let val = -32343.132588105735;
552 let expected = &[
553 0x09, 0x09, 0xc0, 0x0e, 0x0f, 0x95, 0xc8, 0x7c, 0x52, 0xd2, 0x7f,
554 ];
555 let mut buffer = [0u8; 12];
556 let encoded = val.encode_to_slice(&mut buffer).unwrap();
557 assert_eq!(
558 expected, encoded,
559 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
560 val, encoded, expected
561 );
562 let decoded = f64::from_der(encoded).unwrap();
563 assert!(
564 (decoded - val).abs() < f64::EPSILON,
565 "wanted: {}\tgot: {}",
566 val,
567 decoded
568 );
569 }
570
571 {
572 let val = -27084.866751869475;
573 let expected = &[
574 0x09, 0x09, 0xc0, 0x0e, 0x0a, 0x73, 0x37, 0x78, 0xdc, 0xd5, 0x4a,
575 ];
576 let mut buffer = [0u8; 12];
577 let encoded = val.encode_to_slice(&mut buffer).unwrap();
578 assert_eq!(
579 expected, encoded,
580 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
581 val, encoded, expected
582 );
583 let decoded = f64::from_der(encoded).unwrap();
584 assert!(
585 (decoded - val).abs() < f64::EPSILON,
586 "wanted: {}\tgot: {}",
587 val,
588 decoded
589 );
590 }
591
592 {
593 // rec1value R ::= { mantissa -4372913134428149, base 2, exponent 7 }
594 let val = -252.28566647111404;
595 let expected = &[
596 0x09, 0x09, 0xc0, 0x07, 0x0f, 0x89, 0x24, 0x2e, 0x02, 0xdf, 0xf5,
597 ];
598 let mut buffer = [0u8; 12];
599 let encoded = val.encode_to_slice(&mut buffer).unwrap();
600 assert_eq!(
601 expected, encoded,
602 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
603 val, encoded, expected
604 );
605 let decoded = f64::from_der(encoded).unwrap();
606 assert!(
607 (decoded - val).abs() < f64::EPSILON,
608 "wanted: {}\tgot: {}",
609 val,
610 decoded
611 );
612 }
613
614 {
615 let val = -14.399709612928548;
616 let expected = &[
617 0x09, 0x09, 0xc0, 0x03, 0x0c, 0xcc, 0xa6, 0xbd, 0x06, 0xd9, 0x92,
618 ];
619 let mut buffer = [0u8; 12];
620 let encoded = val.encode_to_slice(&mut buffer).unwrap();
621 assert_eq!(
622 expected, encoded,
623 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
624 val, encoded, expected
625 );
626 let decoded = f64::from_der(encoded).unwrap();
627 assert!(
628 (decoded - val).abs() < f64::EPSILON,
629 "wanted: {}\tgot: {}",
630 val,
631 decoded
632 );
633 }
634
635 {
636 let val = -0.08340570261832964;
637 let expected = &[
638 0x09, 0x0a, 0xc1, 0xff, 0xfc, 0x05, 0x5a, 0x13, 0x7d, 0x0b, 0xae, 0x3d,
639 ];
640 let mut buffer = [0u8; 12];
641 let encoded = val.encode_to_slice(&mut buffer).unwrap();
642 assert_eq!(
643 expected, encoded,
644 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
645 val, encoded, expected
646 );
647 let decoded = f64::from_der(encoded).unwrap();
648 assert!(
649 (decoded - val).abs() < f64::EPSILON,
650 "wanted: {}\tgot: {}",
651 val,
652 decoded
653 );
654 }
655
656 {
657 let val = 0.00536851453803701;
658 let expected = &[
659 0x09, 0x0a, 0x81, 0xff, 0xf8, 0x05, 0xfd, 0x4b, 0xa5, 0xe7, 0x4c, 0x93,
660 ];
661 let mut buffer = [0u8; 12];
662 let encoded = val.encode_to_slice(&mut buffer).unwrap();
663 assert_eq!(
664 expected, encoded,
665 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
666 val, encoded, expected
667 );
668 let decoded = f64::from_der(encoded).unwrap();
669 assert!(
670 (decoded - val).abs() < f64::EPSILON,
671 "wanted: {}\tgot: {}",
672 val,
673 decoded
674 );
675 }
676
677 {
678 let val = 0.00045183525648866433;
679 let expected = &[
680 0x09, 0x0a, 0x81, 0xff, 0xf4, 0x0d, 0x9c, 0x89, 0xa6, 0x59, 0x33, 0x39,
681 ];
682 let mut buffer = [0u8; 12];
683 let encoded = val.encode_to_slice(&mut buffer).unwrap();
684 assert_eq!(
685 expected, encoded,
686 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
687 val, encoded, expected
688 );
689 let decoded = f64::from_der(encoded).unwrap();
690 assert!(
691 (decoded - val).abs() < f64::EPSILON,
692 "wanted: {}\tgot: {}",
693 val,
694 decoded
695 );
696 }
697
698 {
699 let val = 0.000033869092002682955;
700 let expected = &[
701 0x09, 0x0a, 0x81, 0xff, 0xf1, 0x01, 0xc1, 0xd5, 0x23, 0xd5, 0x54, 0x7c,
702 ];
703 let mut buffer = [0u8; 12];
704 let encoded = val.encode_to_slice(&mut buffer).unwrap();
705 assert_eq!(
706 expected, encoded,
707 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
708 val, encoded, expected
709 );
710 let decoded = f64::from_der(encoded).unwrap();
711 assert!(
712 (decoded - val).abs() < f64::EPSILON,
713 "wanted: {}\tgot: {}",
714 val,
715 decoded
716 );
717 }
718
719 {
720 let val = 0.0000011770891033600088;
721 let expected = &[
722 0x09, 0x0a, 0x81, 0xff, 0xec, 0x03, 0xbf, 0x8f, 0x27, 0xf4, 0x62, 0x56,
723 ];
724 let mut buffer = [0u8; 12];
725 let encoded = val.encode_to_slice(&mut buffer).unwrap();
726 assert_eq!(
727 expected, encoded,
728 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
729 val, encoded, expected
730 );
731 let decoded = f64::from_der(encoded).unwrap();
732 assert!(
733 (decoded - val).abs() < f64::EPSILON,
734 "wanted: {}\tgot: {}",
735 val,
736 decoded
737 );
738 }
739
740 {
741 let val = 0.00000005549514041997082;
742 let expected = &[
743 0x09, 0x0a, 0x81, 0xff, 0xe7, 0x0d, 0xcb, 0x31, 0xab, 0x6e, 0xb8, 0xd7,
744 ];
745 let mut buffer = [0u8; 12];
746 let encoded = val.encode_to_slice(&mut buffer).unwrap();
747 assert_eq!(
748 expected, encoded,
749 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
750 val, encoded, expected
751 );
752 let decoded = f64::from_der(encoded).unwrap();
753 assert!(
754 (decoded - val).abs() < f64::EPSILON,
755 "wanted: {}\tgot: {}",
756 val,
757 decoded
758 );
759 }
760
761 {
762 let val = 0.0000000012707044685547803;
763 let expected = &[
764 0x09, 0x0a, 0x81, 0xff, 0xe2, 0x05, 0xd4, 0x9e, 0x0a, 0xf2, 0xff, 0x1f,
765 ];
766 let mut buffer = [0u8; 12];
767 let encoded = val.encode_to_slice(&mut buffer).unwrap();
768 assert_eq!(
769 expected, encoded,
770 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
771 val, encoded, expected
772 );
773 let decoded = f64::from_der(encoded).unwrap();
774 assert!(
775 (decoded - val).abs() < f64::EPSILON,
776 "wanted: {}\tgot: {}",
777 val,
778 decoded
779 );
780 }
781
782 {
783 let val = 0.00000000002969611878378562;
784 let expected = &[
785 0x09, 0x09, 0x81, 0xff, 0xdd, 0x53, 0x5b, 0x6f, 0x97, 0xee, 0xb6,
786 ];
787 let mut buffer = [0u8; 11];
788 let encoded = val.encode_to_slice(&mut buffer).unwrap();
789 assert_eq!(
790 expected, encoded,
791 "invalid encoding of {}:\ngot {:x?}\nwant: {:x?}",
792 val, encoded, expected
793 );
794 let decoded = f64::from_der(encoded).unwrap();
795 assert!(
796 (decoded - val).abs() < f64::EPSILON,
797 "wanted: {}\tgot: {}",
798 val,
799 decoded
800 );
801 }
802 }
803
804 #[test]
805 fn reject_non_canonical() {
806 assert!(f64::from_der(&[0x09, 0x81, 0x00]).is_err());
807 }
808
809 #[test]
810 fn encdec_f64() {
811 use super::{decode_f64, encode_f64};
812 // Test that the extraction and recreation works
813 for val in [
814 1.0,
815 0.1,
816 -0.1,
817 -1.0,
818 0.0,
819 f64::MIN_POSITIVE,
820 f64::MAX,
821 f64::MIN,
822 3.1415,
823 951.2357864,
824 -3.1415,
825 -951.2357864,
826 ] {
827 let (s, e, m) = decode_f64(val);
828 let val2 = encode_f64(s, e, m);
829 assert!(
830 (val - val2).abs() < f64::EPSILON,
831 "fail - want {}\tgot {}",
832 val,
833 val2
834 );
835 }
836 }
837
838 #[test]
839 fn validation_cases() {
840 // Caveat: these test cases are validated on the ASN.1 playground: https://asn1.io/asn1playground/ .
841 // The test case consists in inputing the bytes in the "decode" field and checking that the decoded
842 // value corresponds to the one encoded here.
843 // This tool encodes _all_ values that are non-zero in the ISO 6093 NR3 representation.
844 // This does not seem to perfectly adhere to the ITU specifications, Special Cases section.
845 // The implementation of this crate correctly supports decoding such values. It will, however,
846 // systematically encode REALs in their base 2 form, with a scaling factor where needed to
847 // ensure that the mantissa is either odd or zero (as per section 11.3.1).
848
849 // Positive trivial numbers
850 {
851 let expect = 10.0;
852 let testcase = &[0x09, 0x05, 0x03, 0x31, 0x2E, 0x45, 0x31];
853 let decoded = f64::from_der(testcase).unwrap();
854 assert!(
855 (decoded - expect).abs() < f64::EPSILON,
856 "wanted: {}\tgot: {}",
857 expect,
858 decoded
859 );
860 }
861 {
862 let expect = 100.0;
863 let testcase = &[0x09, 0x05, 0x03, 0x31, 0x2E, 0x45, 0x32];
864 let decoded = f64::from_der(testcase).unwrap();
865 assert!(
866 (decoded - expect).abs() < f64::EPSILON,
867 "wanted: {}\tgot: {}",
868 expect,
869 decoded
870 );
871 }
872 {
873 let expect = 101.0;
874 let testcase = &[0x09, 0x08, 0x03, 0x31, 0x30, 0x31, 0x2E, 0x45, 0x2B, 0x30];
875 let decoded = f64::from_der(testcase).unwrap();
876 assert!(
877 (decoded - expect).abs() < f64::EPSILON,
878 "wanted: {}\tgot: {}",
879 expect,
880 decoded
881 );
882 }
883 {
884 let expect = 101.0;
885 let testcase = &[0x09, 0x08, 0x03, 0x31, 0x30, 0x31, 0x2E, 0x45, 0x2B, 0x30];
886 let decoded = f64::from_der(testcase).unwrap();
887 assert!(
888 (decoded - expect).abs() < f64::EPSILON,
889 "wanted: {}\tgot: {}",
890 expect,
891 decoded
892 );
893 }
894 {
895 let expect = 0.0;
896 let testcase = &[0x09, 0x00];
897 let decoded = f64::from_der(testcase).unwrap();
898 assert!(
899 (decoded - expect).abs() < f64::EPSILON,
900 "wanted: {}\tgot: {}",
901 expect,
902 decoded
903 );
904 }
905 {
906 let expect = 951.2357864;
907 let testcase = &[
908 0x09, 0x0F, 0x03, 0x39, 0x35, 0x31, 0x32, 0x33, 0x35, 0x37, 0x38, 0x36, 0x34, 0x2E,
909 0x45, 0x2D, 0x37,
910 ];
911 let decoded = f64::from_der(testcase).unwrap();
912 assert!(
913 (decoded - expect).abs() < f64::EPSILON,
914 "wanted: {}\tgot: {}",
915 expect,
916 decoded
917 );
918 }
919 // Negative trivial numbers
920 {
921 let expect = -10.0;
922 let testcase = &[0x09, 0x06, 0x03, 0x2D, 0x31, 0x2E, 0x45, 0x31];
923 let decoded = f64::from_der(testcase).unwrap();
924 assert!(
925 (decoded - expect).abs() < f64::EPSILON,
926 "wanted: {}\tgot: {}",
927 expect,
928 decoded
929 );
930 }
931 {
932 let expect = -100.0;
933 let testcase = &[0x09, 0x06, 0x03, 0x2D, 0x31, 0x2E, 0x45, 0x32];
934 let decoded = f64::from_der(testcase).unwrap();
935 assert!(
936 (decoded - expect).abs() < f64::EPSILON,
937 "wanted: {}\tgot: {}",
938 expect,
939 decoded
940 );
941 }
942 {
943 let expect = -101.0;
944 let testcase = &[
945 0x09, 0x09, 0x03, 0x2D, 0x31, 0x30, 0x31, 0x2E, 0x45, 0x2B, 0x30,
946 ];
947 let decoded = f64::from_der(testcase).unwrap();
948 assert!(
949 (decoded - expect).abs() < f64::EPSILON,
950 "wanted: {}\tgot: {}",
951 expect,
952 decoded
953 );
954 }
955 {
956 let expect = -0.5;
957 let testcase = &[0x09, 0x07, 0x03, 0x2D, 0x35, 0x2E, 0x45, 0x2D, 0x31];
958 let decoded = f64::from_der(testcase).unwrap();
959 assert!(
960 (decoded - expect).abs() < f64::EPSILON,
961 "wanted: {}\tgot: {}",
962 expect,
963 decoded
964 );
965 }
966 {
967 let expect = -0.0;
968 let testcase = &[0x09, 0x03, 0x01, 0x2D, 0x30];
969 let decoded = f64::from_der(testcase).unwrap();
970 assert!(
971 (decoded - expect).abs() < f64::EPSILON,
972 "wanted: {}\tgot: {}",
973 expect,
974 decoded
975 );
976 }
977 {
978 // Test NR3 decoding
979 let expect = -951.2357864;
980 let testcase = &[
981 0x09, 0x10, 0x03, 0x2D, 0x39, 0x35, 0x31, 0x32, 0x33, 0x35, 0x37, 0x38, 0x36, 0x34,
982 0x2E, 0x45, 0x2D, 0x37,
983 ];
984 let decoded = f64::from_der(testcase).unwrap();
985 assert!(
986 (decoded - expect).abs() < f64::EPSILON,
987 "wanted: {}\tgot: {}",
988 expect,
989 decoded
990 );
991 }
992 }
993 }