sequoia_openpgp/parse/
mpis.rs

1//! Functions for parsing MPIs.
2
3use std::io::Read;
4use buffered_reader::BufferedReader;
5use crate::{
6    Result,
7    Error,
8    PublicKeyAlgorithm,
9    SymmetricAlgorithm,
10    HashAlgorithm,
11};
12use crate::types::Curve;
13use crate::crypto::{
14    mem::Protected,
15    mpi::{self, MPI, ProtectedMPI},
16};
17use crate::parse::{
18    PacketHeaderParser,
19    Cookie,
20};
21
22impl mpi::PublicKey {
23    /// Parses a set of OpenPGP MPIs representing a public key.
24    ///
25    /// See [Section 3.2 of RFC 9580] for details.
26    ///
27    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
28    pub fn parse<R: Read + Send + Sync>(algo: PublicKeyAlgorithm, reader: R) -> Result<Self>
29    {
30        let bio = buffered_reader::Generic::with_cookie(
31            reader, None, Cookie::default());
32        let mut php = PacketHeaderParser::new_naked(bio.into_boxed());
33        Self::_parse(algo, &mut php)
34    }
35
36    /// Parses a set of OpenPGP MPIs representing a public key.
37    ///
38    /// See [Section 3.2 of RFC 9580] for details.
39    ///
40    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
41    pub(crate) fn _parse(
42        algo: PublicKeyAlgorithm,
43        php: &mut PacketHeaderParser<'_>)
44        -> Result<Self>
45    {
46        use crate::PublicKeyAlgorithm::*;
47
48        #[allow(deprecated)]
49        match algo {
50            RSAEncryptSign | RSAEncrypt | RSASign => {
51                let n = MPI::parse("rsa_public_n_len", "rsa_public_n", php)?;
52                let e = MPI::parse("rsa_public_e_len", "rsa_public_e", php)?;
53
54                Ok(mpi::PublicKey::RSA { e, n })
55            }
56
57            DSA => {
58                let p = MPI::parse("dsa_public_p_len", "dsa_public_p", php)?;
59                let q = MPI::parse("dsa_public_q_len", "dsa_public_q", php)?;
60                let g = MPI::parse("dsa_public_g_len", "dsa_public_g", php)?;
61                let y = MPI::parse("dsa_public_y_len", "dsa_public_y", php)?;
62
63                Ok(mpi::PublicKey::DSA {
64                    p,
65                    q,
66                    g,
67                    y,
68                })
69            }
70
71            ElGamalEncrypt | ElGamalEncryptSign => {
72                let p = MPI::parse("elgamal_public_p_len", "elgamal_public_p",
73                                   php)?;
74                let g = MPI::parse("elgamal_public_g_len", "elgamal_public_g",
75                                   php)?;
76                let y = MPI::parse("elgamal_public_y_len", "elgamal_public_y",
77                                   php)?;
78
79                Ok(mpi::PublicKey::ElGamal {
80                    p,
81                    g,
82                    y,
83                })
84            }
85
86            EdDSA => {
87                let curve_len = php.parse_u8("curve_len")? as usize;
88                let curve = php.parse_bytes("curve", curve_len)?;
89                let q = MPI::parse("eddsa_public_len", "eddsa_public", php)?;
90
91                Ok(mpi::PublicKey::EdDSA {
92                    curve: Curve::from_oid(&curve),
93                    q
94                })
95            }
96
97            ECDSA => {
98                let curve_len = php.parse_u8("curve_len")? as usize;
99                let curve = php.parse_bytes("curve", curve_len)?;
100                let q = MPI::parse("ecdsa_public_len", "ecdsa_public", php)?;
101
102                Ok(mpi::PublicKey::ECDSA {
103                    curve: Curve::from_oid(&curve),
104                    q
105                })
106            }
107
108            ECDH => {
109                let curve_len = php.parse_u8("curve_len")? as usize;
110                let curve = php.parse_bytes("curve", curve_len)?;
111                let q = MPI::parse("ecdh_public_len", "ecdh_public", php)?;
112                let kdf_len = php.parse_u8("kdf_len")?;
113
114                if kdf_len != 3 {
115                    return Err(Error::MalformedPacket(
116                            "wrong kdf length".into()).into());
117                }
118
119                let reserved = php.parse_u8("kdf_reserved")?;
120                if reserved != 1 {
121                    return Err(Error::MalformedPacket(
122                            format!("Reserved kdf field must be 0x01, \
123                                     got 0x{:x}", reserved)).into());
124                }
125                let hash: HashAlgorithm = php.parse_u8("kdf_hash")?.into();
126                let sym: SymmetricAlgorithm = php.parse_u8("kek_symm")?.into();
127
128                Ok(mpi::PublicKey::ECDH {
129                    curve: Curve::from_oid(&curve),
130                    q,
131                    hash,
132                    sym
133                })
134            }
135
136            X25519 => {
137                let mut u = [0; 32];
138                php.parse_bytes_into("x25519_public", &mut u)?;
139                Ok(mpi::PublicKey::X25519 { u })
140            },
141
142            X448 => {
143                let mut u = [0; 56];
144                php.parse_bytes_into("x448_public", &mut u)?;
145                Ok(mpi::PublicKey::X448 { u: Box::new(u) })
146            },
147
148            Ed25519 => {
149                let mut a = [0; 32];
150                php.parse_bytes_into("ed25519_public", &mut a)?;
151                Ok(mpi::PublicKey::Ed25519 { a })
152            },
153
154            Ed448 => {
155                let mut a = [0; 57];
156                php.parse_bytes_into("ed448_public", &mut a)?;
157                Ok(mpi::PublicKey::Ed448 { a: Box::new(a) })
158            },
159
160            Unknown(_) | Private(_) => {
161                let mut mpis = Vec::new();
162                while let Ok(mpi) = MPI::parse("unknown_len",
163                                               "unknown", php) {
164                    mpis.push(mpi);
165                }
166                let rest = php.parse_bytes_eof("rest")?;
167
168                Ok(mpi::PublicKey::Unknown {
169                    mpis: mpis.into_boxed_slice(),
170                    rest: rest.into_boxed_slice(),
171                })
172            }
173        }
174    }
175}
176
177impl mpi::SecretKeyMaterial {
178    /// Parses secret key MPIs for `algo` plus their SHA1 checksum.
179    ///
180    /// Fails if the checksum is wrong.
181    #[deprecated(
182        since = "1.14.0",
183        note = "Leaks secrets into the heap, use [`SecretKeyMaterial::from_bytes_with_checksum`]")]
184    pub fn parse_with_checksum<R: Read + Send + Sync>(algo: PublicKeyAlgorithm,
185                                        reader: R,
186                                        checksum: mpi::SecretKeyChecksum)
187                                        -> Result<Self> {
188        let bio = buffered_reader::Generic::with_cookie(
189            reader, None, Cookie::default());
190        let mut php = PacketHeaderParser::new_naked(bio.into_boxed());
191        Self::_parse(algo, &mut php, Some(checksum))
192    }
193
194    /// Parses secret key MPIs for `algo` plus their SHA1 checksum.
195    ///
196    /// Fails if the checksum is wrong.
197    pub fn from_bytes_with_checksum(algo: PublicKeyAlgorithm,
198                                    bytes: &[u8],
199                                    checksum: mpi::SecretKeyChecksum)
200                                    -> Result<Self> {
201        let bio = buffered_reader::Memory::with_cookie(
202            bytes, Cookie::default());
203        let mut php = PacketHeaderParser::new_naked(bio.into_boxed());
204        Self::_parse(algo, &mut php, Some(checksum))
205    }
206
207    /// Parses a set of OpenPGP MPIs representing a secret key.
208    ///
209    /// See [Section 3.2 of RFC 9580] for details.
210    ///
211    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
212    #[deprecated(
213        since = "1.14.0",
214        note = "Leaks secrets into the heap, use [`SecretKeyMaterial::from_bytes`]")]
215    pub fn parse<R: Read + Send + Sync>(algo: PublicKeyAlgorithm, reader: R) -> Result<Self>
216    {
217        let bio = buffered_reader::Generic::with_cookie(
218            reader, None, Cookie::default());
219        let mut php = PacketHeaderParser::new_naked(bio.into_boxed());
220        Self::_parse(algo, &mut php, None)
221    }
222
223    /// Parses a set of OpenPGP MPIs representing a secret key.
224    ///
225    /// See [Section 3.2 of RFC 9580] for details.
226    ///
227    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
228    pub fn from_bytes(algo: PublicKeyAlgorithm, buf: &[u8]) -> Result<Self> {
229        let bio = buffered_reader::Memory::with_cookie(
230            buf, Cookie::default());
231        let mut php = PacketHeaderParser::new_naked(bio.into_boxed());
232        Self::_parse(algo, &mut php, None)
233    }
234
235    /// Parses a set of OpenPGP MPIs representing a secret key.
236    ///
237    /// See [Section 3.2 of RFC 9580] for details.
238    ///
239    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
240    pub(crate) fn _parse(
241        algo: PublicKeyAlgorithm,
242        php: &mut PacketHeaderParser<'_>,
243        checksum: Option<mpi::SecretKeyChecksum>,
244    )
245        -> Result<Self>
246    {
247        use crate::PublicKeyAlgorithm::*;
248
249        // We want to get the data we are going to read next as raw
250        // bytes later.  To do so, we remember the cursor position now
251        // before reading the MPIs.
252        let mpis_start = php.reader.total_out();
253
254        #[allow(deprecated)]
255        let mpis: Result<Self> = match algo {
256            RSAEncryptSign | RSAEncrypt | RSASign => {
257                Ok(mpi::SecretKeyMaterial::RSA {
258                    d: ProtectedMPI::parse(
259                        "rsa_secret_d_len", "rsa_secret_d", php)?,
260                    p: ProtectedMPI::parse(
261                        "rsa_secret_p_len", "rsa_secret_p", php)?,
262                    q: ProtectedMPI::parse(
263                        "rsa_secret_q_len", "rsa_secret_q", php)?,
264                    u: ProtectedMPI::parse(
265                        "rsa_secret_u_len", "rsa_secret_u", php)?,
266                })
267            }
268
269            DSA => {
270                Ok(mpi::SecretKeyMaterial::DSA {
271                    x: ProtectedMPI::parse(
272                        "dsa_secret_len", "dsa_secret", php)?,
273                })
274            }
275
276            ElGamalEncrypt | ElGamalEncryptSign => {
277                Ok(mpi::SecretKeyMaterial::ElGamal {
278                    x: ProtectedMPI::parse(
279                        "elgamal_secret_len", "elgamal_secret", php)?,
280                })
281            }
282
283            EdDSA => {
284                Ok(mpi::SecretKeyMaterial::EdDSA {
285                    scalar: ProtectedMPI::parse(
286                        "eddsa_secret_len", "eddsa_secret", php)?,
287                })
288            }
289
290            ECDSA => {
291                Ok(mpi::SecretKeyMaterial::ECDSA {
292                    scalar: ProtectedMPI::parse(
293                        "ecdsa_secret_len", "ecdsa_secret", php)?,
294                })
295            }
296
297            ECDH => {
298                Ok(mpi::SecretKeyMaterial::ECDH {
299                    scalar: ProtectedMPI::parse(
300                        "ecdh_secret_len", "ecdh_secret", php)?,
301                })
302            }
303
304            X25519 => {
305                let mut x: Protected = vec![0; 32].into();
306                php.parse_bytes_into("x25519_secret", &mut x)?;
307                Ok(mpi::SecretKeyMaterial::X25519 { x })
308            },
309
310            X448 => {
311                let mut x: Protected = vec![0; 56].into();
312                php.parse_bytes_into("x448_secret", &mut x)?;
313                Ok(mpi::SecretKeyMaterial::X448 { x })
314            },
315
316            Ed25519 => {
317                let mut x: Protected = vec![0; 32].into();
318                php.parse_bytes_into("ed25519_secret", &mut x)?;
319                Ok(mpi::SecretKeyMaterial::Ed25519 { x })
320            },
321
322            Ed448 => {
323                let mut x: Protected = vec![0; 57].into();
324                php.parse_bytes_into("ed448_secret", &mut x)?;
325                Ok(mpi::SecretKeyMaterial::Ed448 { x })
326            },
327
328            Unknown(_) | Private(_) => {
329                let mut mpis = Vec::new();
330                while let Ok(mpi) = ProtectedMPI::parse("unknown_len",
331                                               "unknown", php) {
332                    mpis.push(mpi);
333                }
334                let rest = php.parse_bytes_eof("rest")?;
335
336                Ok(mpi::SecretKeyMaterial::Unknown {
337                    mpis: mpis.into_boxed_slice(),
338                    rest: rest.into(),
339                })
340            }
341        };
342        let mpis = mpis?;
343
344        if let Some(checksum) = checksum {
345            // We want to get the data we are going to read next as
346            // raw bytes later.  To do so, we remember the cursor
347            // position now after reading the MPIs and compute the
348            // length.
349            let mpis_len = php.reader.total_out() - mpis_start;
350
351            // We do a bit of acrobatics to avoid copying the secrets.
352            // We read the checksum now, so that we can freely
353            // manipulate the Dup reader and get a borrow of the raw
354            // MPIs.
355            let their_chksum = php.parse_bytes("checksum", checksum.len())?;
356
357            // Remember how much we read in total for a sanity check.
358            let total_out = php.reader.total_out();
359
360            // Now get the secrets as raw byte slice.
361            php.reader.rewind();
362            php.reader.consume(mpis_start);
363            let data = &php.reader.data_consume_hard(mpis_len)?[..mpis_len];
364
365            let good = match checksum {
366                mpi::SecretKeyChecksum::SHA1 => {
367                    // Compute SHA1 hash.
368                    let mut hsh = HashAlgorithm::SHA1.context().unwrap()
369                        .for_digest();
370                    hsh.update(data);
371                    let mut our_chksum = [0u8; 20];
372                    let _ = hsh.digest(&mut our_chksum);
373
374                    our_chksum == their_chksum[..]
375                },
376
377                mpi::SecretKeyChecksum::Sum16 => {
378                    // Compute sum.
379                    let our_chksum = data.iter()
380                        .fold(0u16, |acc, v| acc.wrapping_add(*v as u16))
381                        .to_be_bytes();
382
383                    our_chksum == their_chksum[..]
384                },
385            };
386
387            // Finally, consume the checksum to fix the state of the
388            // Dup reader.
389            php.reader.consume(checksum.len());
390
391            // See if we got the state right.
392            debug_assert_eq!(total_out, php.reader.total_out());
393
394            if good {
395                Ok(mpis)
396            } else {
397                Err(Error::MalformedMPI("checksum wrong".to_string()).into())
398            }
399        } else {
400            Ok(mpis)
401        }
402    }
403}
404
405impl mpi::Ciphertext {
406    /// Parses a set of OpenPGP MPIs representing a ciphertext.
407    ///
408    /// Expects MPIs for a public key algorithm `algo`s ciphertext.
409    /// See [Section 3.2 of RFC 9580] for details.
410    ///
411    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
412    pub fn parse<R: Read + Send + Sync>(algo: PublicKeyAlgorithm, reader: R) -> Result<Self>
413    {
414        let bio = buffered_reader::Generic::with_cookie(
415            reader, None, Cookie::default());
416        let mut php = PacketHeaderParser::new_naked(bio.into_boxed());
417        Self::_parse(algo, &mut php)
418    }
419
420    /// Parses a set of OpenPGP MPIs representing a ciphertext.
421    ///
422    /// Expects MPIs for a public key algorithm `algo`s ciphertext.
423    /// See [Section 3.2 of RFC 9580] for details.
424    ///
425    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
426    pub(crate) fn _parse(
427        algo: PublicKeyAlgorithm,
428        php: &mut PacketHeaderParser<'_>)
429        -> Result<Self> {
430        use crate::PublicKeyAlgorithm::*;
431
432        #[allow(deprecated)]
433        match algo {
434            RSAEncryptSign | RSAEncrypt => {
435                let c = MPI::parse("rsa_ciphertxt_len", "rsa_ciphertxt",
436                                   php)?;
437
438                Ok(mpi::Ciphertext::RSA {
439                    c,
440                })
441            }
442
443            ElGamalEncrypt | ElGamalEncryptSign => {
444                let e = MPI::parse("elgamal_e_len", "elgamal_e", php)?;
445                let c = MPI::parse("elgamal_c_len", "elgamal_c", php)?;
446
447                Ok(mpi::Ciphertext::ElGamal {
448                    e,
449                    c,
450                })
451            }
452
453            ECDH => {
454                let e = MPI::parse("ecdh_e_len", "ecdh_e", php)?;
455                let key_len = php.parse_u8("ecdh_esk_len")? as usize;
456                let key = Vec::from(&php.parse_bytes("ecdh_esk", key_len)?
457                                    [..key_len]);
458
459                Ok(mpi::Ciphertext::ECDH {
460                    e, key: key.into_boxed_slice()
461                })
462            }
463
464            X25519 => {
465                let mut e = [0; 32];
466                php.parse_bytes_into("x25519_e", &mut e)?;
467                let key_len = php.parse_u8("x25519_esk_len")? as usize;
468                let key = Vec::from(&php.parse_bytes("x25519_esk", key_len)?
469                                    [..key_len]);
470                Ok(mpi::Ciphertext::X25519 { e: Box::new(e), key: key.into() })
471            },
472
473            X448 => {
474                let mut e = [0; 56];
475                php.parse_bytes_into("x448_e", &mut e)?;
476                let key_len = php.parse_u8("x448_esk_len")? as usize;
477                let key = Vec::from(&php.parse_bytes("x448_esk", key_len)?
478                                    [..key_len]);
479                Ok(mpi::Ciphertext::X448 { e: Box::new(e), key: key.into() })
480            },
481
482            Unknown(_) | Private(_) => {
483                let mut mpis = Vec::new();
484                while let Ok(mpi) = MPI::parse("unknown_len",
485                                               "unknown", php) {
486                    mpis.push(mpi);
487                }
488                let rest = php.parse_bytes_eof("rest")?;
489
490                Ok(mpi::Ciphertext::Unknown {
491                    mpis: mpis.into_boxed_slice(),
492                    rest: rest.into_boxed_slice(),
493                })
494            }
495
496            RSASign | DSA | EdDSA | ECDSA | Ed25519 | Ed448
497                => Err(Error::InvalidArgument(
498                    format!("not an encryption algorithm: {:?}", algo)).into()),
499        }
500    }
501}
502
503impl mpi::Signature {
504    /// Parses a set of OpenPGP MPIs representing a signature.
505    ///
506    /// Expects MPIs for a public key algorithm `algo`s signature.
507    /// See [Section 3.2 of RFC 9580] for details.
508    ///
509    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
510    pub fn parse<R: Read + Send + Sync>(algo: PublicKeyAlgorithm, reader: R) -> Result<Self>
511    {
512        let bio = buffered_reader::Generic::with_cookie(
513            reader, None, Cookie::default());
514        let mut php = PacketHeaderParser::new_naked(bio.into_boxed());
515        Self::_parse(algo, &mut php)
516    }
517
518    /// Parses a set of OpenPGP MPIs representing a signature.
519    ///
520    /// Expects MPIs for a public key algorithm `algo`s signature.
521    /// See [Section 3.2 of RFC 9580] for details.
522    ///
523    ///   [Section 3.2 of RFC 9580]: https://www.rfc-editor.org/rfc/rfc9580.html#section-3.2
524    pub(crate) fn _parse(
525        algo: PublicKeyAlgorithm,
526        php: &mut PacketHeaderParser<'_>)
527        -> Result<Self> {
528        use crate::PublicKeyAlgorithm::*;
529
530        #[allow(deprecated)]
531        match algo {
532            RSAEncryptSign | RSASign => {
533                let s = MPI::parse("rsa_signature_len", "rsa_signature", php)?;
534
535                Ok(mpi::Signature::RSA {
536                    s,
537                })
538            }
539
540            DSA => {
541                let r = MPI::parse("dsa_sig_r_len", "dsa_sig_r",
542                                   php)?;
543                let s = MPI::parse("dsa_sig_s_len", "dsa_sig_s",
544                                   php)?;
545
546                Ok(mpi::Signature::DSA {
547                    r,
548                    s,
549                })
550            }
551
552            ElGamalEncryptSign => {
553                let r = MPI::parse("elgamal_sig_r_len",
554                                   "elgamal_sig_r", php)?;
555                let s = MPI::parse("elgamal_sig_s_len",
556                                   "elgamal_sig_s", php)?;
557
558                Ok(mpi::Signature::ElGamal {
559                    r,
560                    s,
561                })
562            }
563
564            EdDSA => {
565                let r = MPI::parse("eddsa_sig_r_len", "eddsa_sig_r",
566                                   php)?;
567                let s = MPI::parse("eddsa_sig_s_len", "eddsa_sig_s",
568                                   php)?;
569
570                Ok(mpi::Signature::EdDSA {
571                    r,
572                    s,
573                })
574            }
575
576            ECDSA => {
577                let r = MPI::parse("ecdsa_sig_r_len", "ecdsa_sig_r",
578                                   php)?;
579                let s = MPI::parse("ecdsa_sig_s_len", "ecdsa_sig_s",
580                                   php)?;
581
582                Ok(mpi::Signature::ECDSA {
583                    r,
584                    s,
585                })
586            }
587
588            Ed25519 => {
589                let mut s = [0; 64];
590                php.parse_bytes_into("ed25519_sig", &mut s)?;
591                Ok(mpi::Signature::Ed25519 { s: Box::new(s) })
592            },
593
594            Ed448 => {
595                let mut s = [0; 114];
596                php.parse_bytes_into("ed448_sig", &mut s)?;
597                Ok(mpi::Signature::Ed448 { s: Box::new(s) })
598            },
599
600            Unknown(_) | Private(_) => {
601                let mut mpis = Vec::new();
602                while let Ok(mpi) = MPI::parse("unknown_len",
603                                               "unknown", php) {
604                    mpis.push(mpi);
605                }
606                let rest = php.parse_bytes_eof("rest")?;
607
608                Ok(mpi::Signature::Unknown {
609                    mpis: mpis.into_boxed_slice(),
610                    rest: rest.into_boxed_slice(),
611                })
612            }
613
614            RSAEncrypt | ElGamalEncrypt | ECDH | X25519 | X448
615                => Err(Error::InvalidArgument(
616                    format!("not a signature algorithm: {:?}", algo)).into()),
617        }
618    }
619}
620
621#[test]
622fn mpis_parse_test() {
623    use std::io::Cursor;
624    use super::Parse;
625    use crate::PublicKeyAlgorithm::*;
626    use crate::serialize::MarshalInto;
627
628    // Dummy RSA public key.
629    {
630        let buf = Cursor::new("\x00\x01\x01\x00\x02\x02");
631        let mpis = mpi::PublicKey::parse(RSAEncryptSign, buf).unwrap();
632
633        //assert_eq!(mpis.serialized_len(), 6);
634        match &mpis {
635            &mpi::PublicKey::RSA{ ref n, ref e } => {
636                assert_eq!(n.bits(), 1);
637                assert_eq!(n.value()[0], 1);
638                assert_eq!(n.value().len(), 1);
639                assert_eq!(e.bits(), 2);
640                assert_eq!(e.value()[0], 2);
641                assert_eq!(e.value().len(), 1);
642            }
643
644            _ => assert!(false),
645        }
646    }
647
648    // The number 2.
649    {
650        let buf = Cursor::new("\x00\x02\x02");
651        let mpis = mpi::Ciphertext::parse(RSAEncryptSign, buf).unwrap();
652
653        assert_eq!(mpis.serialized_len(), 3);
654    }
655
656    // The number 511.
657    let mpi = MPI::from_bytes(b"\x00\x09\x01\xff").unwrap();
658    assert_eq!(mpi.value().len(), 2);
659    assert_eq!(mpi.bits(), 9);
660    assert_eq!(mpi.value()[0], 1);
661    assert_eq!(mpi.value()[1], 0xff);
662
663    // The number 1, incorrectly encoded (the length should be 1,
664    // not 2).
665    assert!(MPI::from_bytes(b"\x00\x02\x01").is_err());
666}