1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
#![no_std] //! Mashup of [TweetNaCl](tweetnacl) with [ed25519-dalek](ed25519-dalek), //! aimed towards embedded use cases on microcontrollers. //! //! Originally, this library was a transliteration of the C implementation of //! Ed25519 signatures in TweetNaCl to Rust, "with helpful explanations". //! One reason the current ed25519-dalek library in its current state is not //! usable for microcontrollers is that it includes ~40kB of pre-computed data //! to speed things up. Moreover, the implementatons are optimized for PC. //! //! Iterating over the not-very-nice API surface of NaCl, we ended up with //! a close relative of the "[dalek](dalek)" APIs anyway, where things are modeled as, //! for instance, "compressed y-coordinate of Edwards25519 curve point", //! instead of raw bytes. //! //! The main entry point of the API is either a keypair, or a public key. //! //! For keypairs, an external trusted source of entropy is assumed, letting //! us construct a keypair as: //! //! ```ignore //! let seed: [u8; 32] = <some entropic input>; //! let keypair: salty::Keypair = salty::Keypair::from(&seed); //! ``` //! //! Any byte slice that fits in memory can then be signed (without new //! entropic input) deterministically via //! //! ```ignore //! let data: &[u8] = <some data>; //! let signature: salty::Signature = keypair.sign(data); //! ``` //! //! Thereafter, the signature can be checked: //! //! ```ignore //! let public_key = &keypair.pubic; //! assert!(public_key.verify(data, &signature).is_ok()); //! ``` //! //! Please note that `Ed25519` signatures are *not* init-update-finalize signatures, //! since two passes over the data are made, sequentially (the output of the first pass //! is an input to the second pass). //! For cases where the data to be signed does not fit in memory, as explained in //! [RFC 8032](rfc-8032) an alternative algorithm `Ed25519ph` ("ph" for prehashed) is //! defined. This is *not* the same as applying Ed25519 signature to the SHA512 hash of //! the data; it is is exposed via `Keypair::sign_prehashed` and //! `PublicKey::verify_prehashed`. //! //! Future plans include: //! - rigorous correctness checks //! - rigorous checks against timing side-channels, using the DWT cycle count of ARM MCUs //! - optimize the field operations for Cortex-M4 and above, by using the //! implementation provided by Bjoern Haase which is based on the the UMAAL instruction //! `(u32, u32, u32, u32) -> u64, (a, b, c, d) -> a*b + c + d`. //! - add the authenticated encryption part of NaCl //! - add more lightweight cryptography as alternative //! //! Current numbers on an NXP LPC55S69 running at 96Mhz: //! - signing prehashed message: 52,632,954 cycles //! - verifying said message: 100,102,158 cycles //! - code size for this: 19,724 bytes //! Obviously, this needs to improve :)) //! //! [tweetnacl]: https://tweetnacl.cr.yp.to/ //! [ed25519-dalek]: https://lib.rs/crates/ed25519-dalek //! [dalek]: https://dalek.rs/ //! [rfc-8032]: https://tools.ietf.org/html/rfc8032/ /// Extensible error type for all `salty` operations. /// /// This enum has a hidden member, to prevent exhaustively checking for errors. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum Error { /// Signature verification failed SignatureInvalid, #[doc(hidden)] _Extensible, } /// Result type for all `salty` operations. pub type Result<T = ()> = core::result::Result<T, Error>; pub mod constants; /// Self-contained implementation of SHA512 mod hash; pub use hash::Sha512; /// Implementation of underlying curve base field arithmetic mod field; mod scalar; pub use scalar::Scalar; mod curve; pub use curve::{CurvePoint, CompressedY}; mod keys; pub use keys::{SecretKey, PublicKey, Keypair, Signature}; // mod internal; // mod traits; // /// The base field Z mod 2^255 - 19 // // #[cfg(feature = "cortex-m4")] // // pub mod field_haase as field; // // #[!cfg(feature = "cortex-m4")] // // pub mod field_tweetnacl as field; // pub mod field; // // pub mod field_haase; // /// The twisted Edwards curve // pub mod curve; // /// SHA-512 // pub mod hash; // /// Ed25519 signatures // pub mod sign; // // pub mod field_common; // #[cfg(test)] // mod tests;