From ebf0801dfce8b18f13729e8de9bac8b4080acbc7 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Wed, 4 Jul 2018 20:50:22 +0000 Subject: [PATCH 01/14] Update warning statement on production readiness in README. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ddf4283..5e59cfa 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,10 @@ prime-order group from a non-prime-order Edwards curve. This provides the speed and safety benefits of Edwards curve arithmetic, without the pitfalls of cofactor-related abstraction mismatches. -## WARNING +## Stability -We do not yet consider this code to be production-ready. We intend to -stabilize a production-ready version `1.0` soon. +We have recently released a `1.0.0-pre.0` version of `curve25519-dalek` and +would greatly appreciate testing and feedback on our API and performance. # Documentation From 4a54f66a48b6d30ace6c400b74b30001c389d054 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Wed, 4 Jul 2018 20:54:05 +0000 Subject: [PATCH 02/14] Move documentation of yolocrypto feature in README. --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5e59cfa..fe086d6 100644 --- a/README.md +++ b/README.md @@ -59,10 +59,6 @@ extern crate curve25519_dalek; # Backends and Features -The `yolocrypto` feature enables experimental features. The name `yolocrypto` -is meant to indicate that it is not considered production-ready, and we do not -consider `yolocrypto` features to be covered by semver guarantees. - The `std` feature is enabled by default, but it can be disabled. The `nightly` feature enables nightly-only features. **It is recommended for security**. @@ -93,6 +89,13 @@ cargo bench --no-default-features --features "std u64_backend" cargo bench --no-default-features --features "std avx2_backend" ``` +The `yolocrypto` feature enables experimental features. The name `yolocrypto` +is meant to indicate that it is not considered production-ready, and we do not +consider `yolocrypto` features to be covered by semver guarantees. +This is designed to make it easier to test intended new features +without having to stabilise them first. Use `yolocrypto` at your own, +obvious, risk. + # Contributing Please see [CONTRIBUTING.md][contributing]. From 1b52b4b7b7af109993af2f8ae0a50f486201c367 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Wed, 4 Jul 2018 20:59:37 +0000 Subject: [PATCH 03/14] Thank Sean Bowe and Daira Hopwood in the README. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fe086d6..751d043 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,8 @@ turn a port of the reference `ref10` implementation. Most of this code, including the 32-bit field arithmetic, has since been rewritten. The fast `u32` and `u64` scalar arithmetic was implemented by Andrew Moon, and -the addition chain for scalar inversion was provided by Brian Smith. +the addition chain for scalar inversion was provided by Brian Smith. The +optimised batch inversion was contributed by Sean Bowe and Daira Hopwood. The `no_std` support was contributed by Tony Arcieri. From f4669c8b4d78f217a794f671c35457065d920508 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Wed, 4 Jul 2018 21:29:36 +0000 Subject: [PATCH 04/14] Move the Scalar constructor documentation to the module level. --- src/scalar.rs | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/scalar.rs b/src/scalar.rs index 7e02637..2ed4bde 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -11,6 +11,28 @@ // - Brian Smith //! Arithmetic on scalars (integers mod the group order). +//! +//! Both the Ristretto group and the Ed25519 basepoint have prime order +//! \\( \ell = 2\^{252} + 27742317777372353535851937790883648493 \\). +//! +//! This code is intended to be useful with both the Ristretto group +//! (where everything is done modulo \\( \ell \\)), and the X/Ed25519 +//! setting, which mandates specific bit-twiddles that are not +//! well-defined modulo \\( \ell \\). +//! +//! To create a `Scalar` from a supposedly canonical encoding, use +//! `Scalar::from_canonical_bytes`. +//! +//! To create a `Scalar` by reducing a \\(256\\)-bit integer mod \\( \ell \\), +//! use `Scalar::from_bytes_mod_order`. +//! +//! To create a `Scalar` by reducing a \\(512\\)-bit integer mod \\( \ell \\), +//! use `Scalar::from_bytes_mod_order_wide`. +//! +//! To create a `Scalar` with a specific bit-pattern (e.g., for +//! compatibility with X25519 "clamping"), use `Scalar::from_bits`. +//! +//! All arithmetic on `Scalars` is done modulo \\( \ell \\). use core::fmt::Debug; use core::ops::Neg; @@ -51,28 +73,6 @@ type UnpackedScalar = backend::u32::scalar::Scalar32; /// The `Scalar` struct holds an integer \\(s < 2\^{255} \\) which /// represents an element of \\(\mathbb Z / \ell\\). -/// -/// Both the Ristretto group and the Ed25519 basepoint have prime order -/// \\( \ell = 2\^{252} + 27742317777372353535851937790883648493 \\). -/// -/// The code is intended to be useful with both the Ristretto group -/// (where everything is done modulo \\( \ell \\)), and the X/Ed25519 -/// setting, which mandates specific bit-twiddles that are not -/// well-defined modulo \\( \ell \\). -/// -/// To create a `Scalar` from a supposedly canonical encoding, use -/// `Scalar::from_canonical_bytes`. -/// -/// To create a `Scalar` by reducing a \\(256\\)-bit integer mod \\( \ell \\), -/// use `Scalar::from_bytes_mod_order`. -/// -/// To create a `Scalar` by reducing a \\(512\\)-bit integer mod \\( \ell \\), -/// use `Scalar::from_bytes_mod_order_wide`. -/// -/// To create a `Scalar` with a specific bit-pattern (e.g., for -/// compatibility with X25519 "clamping"), use `Scalar::from_bits`. -/// -/// All arithmetic on `Scalars` is done modulo \\( \ell \\). #[derive(Copy, Clone)] pub struct Scalar { /// `bytes` is a little-endian byte encoding of an integer representing a scalar modulo the group order. From b3da93b069f3e7620db10eccf61dd1b8f459094b Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Wed, 4 Jul 2018 21:36:57 +0000 Subject: [PATCH 05/14] Clarify README documentation on nightly-only features. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 751d043..4f09ba5 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,8 @@ extern crate curve25519_dalek; The `std` feature is enabled by default, but it can be disabled. -The `nightly` feature enables nightly-only features. **It is recommended for security**. +The `nightly` feature enables features available only when using a Rust nightly +compiler. **It is recommended for security**. Curve arithmetic is implemented using one of the following backends: From 5b263dabd0e8e2c752b45217dda8bc18600350cf Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Wed, 4 Jul 2018 21:43:13 +0000 Subject: [PATCH 06/14] Line wrap some docstrings in scalar.rs. --- src/scalar.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/scalar.rs b/src/scalar.rs index 2ed4bde..4616e67 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -75,14 +75,18 @@ type UnpackedScalar = backend::u32::scalar::Scalar32; /// represents an element of \\(\mathbb Z / \ell\\). #[derive(Copy, Clone)] pub struct Scalar { - /// `bytes` is a little-endian byte encoding of an integer representing a scalar modulo the group order. + /// `bytes` is a little-endian byte encoding of an integer representing a scalar modulo the + /// group order. /// /// # Invariant /// - /// The integer representing this scalar must be bounded above by \\(2\^{255}\\), or equivalently the high bit of `bytes[31]` must be zero. + /// The integer representing this scalar must be bounded above by \\(2\^{255}\\), or + /// equivalently the high bit of `bytes[31]` must be zero. /// /// This ensures that there is room for a carry bit when computing a NAF representation. - // XXX This is pub(crate) so we can write literal constants. If const fns were stable, we could make the Scalar constructors const fns and use those instead. + // + // XXX This is pub(crate) so we can write literal constants. If const fns were stable, we could + // make the Scalar constructors const fns and use those instead. pub(crate) bytes: [u8; 32], } From 626e070896793cae2c5b997612ef4a22a558a323 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Wed, 4 Jul 2018 23:36:18 +0000 Subject: [PATCH 07/14] Document Scalar contructors with doctests. --- src/scalar.rs | 130 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 118 insertions(+), 12 deletions(-) diff --git a/src/scalar.rs b/src/scalar.rs index 4616e67..1004f57 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -20,19 +20,125 @@ //! setting, which mandates specific bit-twiddles that are not //! well-defined modulo \\( \ell \\). //! -//! To create a `Scalar` from a supposedly canonical encoding, use -//! `Scalar::from_canonical_bytes`. -//! -//! To create a `Scalar` by reducing a \\(256\\)-bit integer mod \\( \ell \\), -//! use `Scalar::from_bytes_mod_order`. -//! -//! To create a `Scalar` by reducing a \\(512\\)-bit integer mod \\( \ell \\), -//! use `Scalar::from_bytes_mod_order_wide`. -//! -//! To create a `Scalar` with a specific bit-pattern (e.g., for -//! compatibility with X25519 "clamping"), use `Scalar::from_bits`. -//! //! All arithmetic on `Scalars` is done modulo \\( \ell \\). +//! +//! # Constructing a scalar +//! +//! To create a [`Scalar`](struct.Scalar.html) from a supposedly canonical encoding, use +//! [`Scalar::from_canonical_bytes`](struct.Scalar.html#method.from_canonical_bytes). +//! +//! If the bytes are a canonical encoding of a scalar mod \ell, we'll get +//! `Some(Scalar)` in return: +//! +//! ``` +//! use curve25519_dalek::scalar::Scalar; +//! +//! let one_as_bytes: [u8; 32] = Scalar::one().to_bytes(); +//! let a: Option = Scalar::from_canonical_bytes(one_as_bytes); +//! +//! assert!(a.is_some()); +//! ``` +//! +//! However, if we give it bytes representing a scalar larger than \\( \ell \\) +//! (in this case, \\( \ell + 2 \\)), we'll get `None` back: +//! +//! ``` +//! use curve25519_dalek::scalar::Scalar; +//! +//! let l_plus_two_bytes: [u8; 32] = [ +//! 0xef, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, +//! 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, +//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +//! ]; +//! let a: Option = Scalar::from_canonical_bytes(l_plus_two_bytes); +//! +//! assert!(a.is_none()); +//! ``` +//! +//! Another way to create a `Scalar` is by reducing a \\(256\\)-bit integer mod +//! \\( \ell \\), for which one may use the +//! [`Scalar::from_bytes_mod_order`](struct.Scalar.html#method.from_bytes_mod_order) +//! method. In the case of the second example above, this would reduce the +//! resultant scalar \\( \mod \ell \\), producing \\( 2 \\): +//! +//! ``` +//! use curve25519_dalek::scalar::Scalar; +//! +//! let l_plus_two_bytes: [u8; 32] = [ +//! 0xef, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, +//! 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, +//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +//! ]; +//! let a: Scalar = Scalar::from_bytes_mod_order(l_plus_two_bytes); +//! +//! let two: Scalar = Scalar::one() + Scalar::one(); +//! +//! assert!(a == two); +//! ``` +//! +//! Similarly, to create a `Scalar` by reducing a \\(512\\)-bit integer mod \\( +//! \ell \\), use +//! [`Scalar::from_bytes_mod_order_wide`](struct.Scalar.html#method.from_bytes_mod_order_wide). +//! This is most frequently used to produce a `Scalar` from the output of a +//! 512-bit hash function: +//! +//! ``` +//! # extern crate curve25519_dalek; +//! # extern crate digest; +//! # extern crate sha2; +//! # +//! # fn main() { +//! use curve25519_dalek::scalar::Scalar; +//! +//! use digest::Input; +//! +//! use sha2::Digest; +//! use sha2::Sha512; +//! +//! let mut hasher: Sha512 = Sha512::default(); +//! let mut hash: [u8; 64] = [0u8; 64]; +//! +//! hasher.input(b"Abolish ICE"); +//! hash.copy_from_slice(hasher.result().as_slice()); +//! +//! let a: Scalar = Scalar::from_bytes_mod_order_wide(&hash); +//! # } +//! ``` +//! +//! However, for hashes in particular, there are also the convenience methods +//! [`Scalar::from_hash`](struct.Scalar.html#method.from_hash) and +//! [`Scalar::hash_from_bytes`](struct.Scalar.html#method.hash_from_bytes). +//! +//! To create a `Scalar` with a specific bit-pattern (e.g., for compatibility +//! with X25519 +//! ["clamping"](https://github.com/isislovecruft/ed25519-dalek/blob/f790bd2ce/src/ed25519.rs#L349)), +//! use [`Scalar::from_bits`](struct.Scalar.html#method.from_bits). This +//! constructs a scalar with exactly the bit pattern given, without any +//! assurances as to reduction modulo the group order: +//! +//! ``` +//! use curve25519_dalek::scalar::Scalar; +//! +//! let l_plus_two_bytes: [u8; 32] = [ +//! 0xef, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, +//! 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, +//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +//! ]; +//! let a: Scalar = Scalar::from_bits(l_plus_two_bytes); +//! +//! let two: Scalar = Scalar::one() + Scalar::one(); +//! +//! assert!(a != two); // the scalar is not reduced (mod l)… +//! assert!(! a.is_canonical()); // …and therefore is not canonical. +//! assert!(a.reduce() == two); // if we were to reduce it manually, it would be. +//! ``` +//! +//! In particular, the bit pattern for the resulting scalar is invariant, +//! **except for the high bit, which will be unset** in order to preserve the +//! condition that scalars are 255-bit integers. use core::fmt::Debug; use core::ops::Neg; From faf860924626ec084db0f5ef64737890bdbac4a0 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Thu, 5 Jul 2018 00:14:55 +0000 Subject: [PATCH 08/14] Copy the inversions of 0 warning to the invert() method. --- src/scalar.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/scalar.rs b/src/scalar.rs index 1004f57..7e23699 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -525,6 +525,16 @@ impl Scalar { } /// Compute the multiplicative inverse of this scalar. + /// + /// # Warning + /// + /// All input `Scalars` **MUST** be nonzero. If you cannot + /// *prove* that this is the case, you **SHOULD NOT USE THIS + /// FUNCTION**. + /// + /// # Returns + /// + /// The multiplicative inverse of the this `Scalar`. pub fn invert(&self) -> Scalar { self.unpack().invert().pack() } From 03154d47ec1ff8f12064ed8441d71ca59106fafb Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Thu, 5 Jul 2018 00:15:15 +0000 Subject: [PATCH 09/14] Add an example doctest for Scalar.invert(). --- src/scalar.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/scalar.rs b/src/scalar.rs index 7e23699..b700368 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -535,6 +535,32 @@ impl Scalar { /// # Returns /// /// The multiplicative inverse of the this `Scalar`. + /// + /// # Example + /// + /// ``` + /// use curve25519_dalek::scalar::Scalar; + /// + /// // x = 2238329342913194256032495932344128051776374960164957527413114840482143558222 + /// let X: Scalar = Scalar::from_bytes_mod_order([ + /// 0x4e, 0x5a, 0xb4, 0x34, 0x5d, 0x47, 0x08, 0x84, + /// 0x59, 0x13, 0xb4, 0x64, 0x1b, 0xc2, 0x7d, 0x52, + /// 0x52, 0xa5, 0x85, 0x10, 0x1b, 0xcc, 0x42, 0x44, + /// 0xd4, 0x49, 0xf4, 0xa8, 0x79, 0xd9, 0xf2, 0x04, + /// ]); + /// // 1/x = 6859937278830797291664592131120606308688036382723378951768035303146619657244 + /// let XINV: Scalar = Scalar::from_bytes_mod_order([ + /// 0x1c, 0xdc, 0x17, 0xfc, 0xe0, 0xe9, 0xa5, 0xbb, + /// 0xd9, 0x24, 0x7e, 0x56, 0xbb, 0x01, 0x63, 0x47, + /// 0xbb, 0xba, 0x31, 0xed, 0xd5, 0xa9, 0xbb, 0x96, + /// 0xd5, 0x0b, 0xcd, 0x7a, 0x3f, 0x96, 0x2a, 0x0f, + /// ]); + /// + /// let inv_X: Scalar = X.invert(); + /// assert!(XINV == inv_X); + /// let should_be_one: Scalar = &inv_X * &X; + /// assert!(should_be_one == Scalar::one()); + /// ``` pub fn invert(&self) -> Scalar { self.unpack().invert().pack() } From f43f4f977080b83886f0e6a8636938701b7b49d3 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Thu, 5 Jul 2018 00:24:41 +0000 Subject: [PATCH 10/14] Update year in copyright notices to 2018. --- LICENSE | 2 +- src/backend/avx2/constants.rs | 2 +- src/backend/avx2/edwards.rs | 2 +- src/backend/avx2/field.rs | 2 +- src/backend/avx2/mod.rs | 2 +- src/backend/mod.rs | 2 +- src/backend/u32/constants.rs | 2 +- src/backend/u32/field.rs | 2 +- src/backend/u32/mod.rs | 2 +- src/backend/u64/constants.rs | 2 +- src/backend/u64/field.rs | 2 +- src/backend/u64/mod.rs | 2 +- src/constants.rs | 2 +- src/curve_models/mod.rs | 2 +- src/edwards.rs | 2 +- src/field.rs | 2 +- src/lib.rs | 2 +- src/macros.rs | 2 +- src/montgomery.rs | 2 +- src/ristretto.rs | 2 +- src/scalar.rs | 2 +- src/scalar_mul/window.rs | 2 +- src/traits.rs | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/LICENSE b/LICENSE index 33ed368..d94fdb5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved. +Copyright (c) 2016-2018 Isis Agora Lovecruft, Henry de Valence. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/src/backend/avx2/constants.rs b/src/backend/avx2/constants.rs index 304a1be..fa31c9d 100644 --- a/src/backend/avx2/constants.rs +++ b/src/backend/avx2/constants.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/avx2/edwards.rs b/src/backend/avx2/edwards.rs index 43f02f7..d9f0b01 100644 --- a/src/backend/avx2/edwards.rs +++ b/src/backend/avx2/edwards.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/avx2/field.rs b/src/backend/avx2/field.rs index 175ff14..173d28e 100644 --- a/src/backend/avx2/field.rs +++ b/src/backend/avx2/field.rs @@ -1,7 +1,7 @@ // -*- mode: rust; coding: utf-8; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/avx2/mod.rs b/src/backend/avx2/mod.rs index b13ea1d..14a2fcb 100644 --- a/src/backend/avx2/mod.rs +++ b/src/backend/avx2/mod.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/mod.rs b/src/backend/mod.rs index aa44d52..d325715 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/u32/constants.rs b/src/backend/u32/constants.rs index f68f662..e0e0525 100644 --- a/src/backend/u32/constants.rs +++ b/src/backend/u32/constants.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/u32/field.rs b/src/backend/u32/field.rs index 8c65a46..9de460a 100644 --- a/src/backend/u32/field.rs +++ b/src/backend/u32/field.rs @@ -1,7 +1,7 @@ // -*- mode: rust; coding: utf-8; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/u32/mod.rs b/src/backend/u32/mod.rs index bc1148e..4d6bc8b 100644 --- a/src/backend/u32/mod.rs +++ b/src/backend/u32/mod.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/u64/constants.rs b/src/backend/u64/constants.rs index 20ecb7f..0ac7fe3 100644 --- a/src/backend/u64/constants.rs +++ b/src/backend/u64/constants.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/u64/field.rs b/src/backend/u64/field.rs index d685ff3..25a013e 100644 --- a/src/backend/u64/field.rs +++ b/src/backend/u64/field.rs @@ -1,7 +1,7 @@ // -*- mode: rust; coding: utf-8; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/backend/u64/mod.rs b/src/backend/u64/mod.rs index a72dc0f..d329a89 100644 --- a/src/backend/u64/mod.rs +++ b/src/backend/u64/mod.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/constants.rs b/src/constants.rs index fd8298c..c990b09 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/curve_models/mod.rs b/src/curve_models/mod.rs index a88c37d..45c2919 100644 --- a/src/curve_models/mod.rs +++ b/src/curve_models/mod.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/edwards.rs b/src/edwards.rs index 5f03929..1fb4d07 100644 --- a/src/edwards.rs +++ b/src/edwards.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/field.rs b/src/field.rs index c9f4c49..2241c13 100644 --- a/src/field.rs +++ b/src/field.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/lib.rs b/src/lib.rs index 70f80f5..c28ff31 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/macros.rs b/src/macros.rs index 448d32c..3ec9d77 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/montgomery.rs b/src/montgomery.rs index 0b8450d..0c21b00 100644 --- a/src/montgomery.rs +++ b/src/montgomery.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/ristretto.rs b/src/ristretto.rs index 78cd178..5581a19 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/scalar.rs b/src/scalar.rs index b700368..4f0863e 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // Portions Copyright 2017 Brian Smith // See LICENSE for licensing information. // diff --git a/src/scalar_mul/window.rs b/src/scalar_mul/window.rs index 91ebb65..c116136 100644 --- a/src/scalar_mul/window.rs +++ b/src/scalar_mul/window.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: diff --git a/src/traits.rs b/src/traits.rs index e706348..aac84d0 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,7 +1,7 @@ // -*- mode: rust; -*- // // This file is part of curve25519-dalek. -// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence +// Copyright (c) 2016-2018 Isis Lovecruft, Henry de Valence // See LICENSE for licensing information. // // Authors: From b70b32a0c55fb8267680ad1d4cc9fc8e3f1a4568 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Jul 2018 13:27:09 -0700 Subject: [PATCH 11/14] Change Scalar example to use the hasher functions --- src/scalar.rs | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/scalar.rs b/src/scalar.rs index 4f0863e..705034f 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -27,7 +27,9 @@ //! To create a [`Scalar`](struct.Scalar.html) from a supposedly canonical encoding, use //! [`Scalar::from_canonical_bytes`](struct.Scalar.html#method.from_canonical_bytes). //! -//! If the bytes are a canonical encoding of a scalar mod \ell, we'll get +//! This function does input validation, ensuring that the input bytes +//! are the canonical encoding of a `Scalar`. +//! If they are, we'll get //! `Some(Scalar)` in return: //! //! ``` @@ -78,41 +80,38 @@ //! assert!(a == two); //! ``` //! -//! Similarly, to create a `Scalar` by reducing a \\(512\\)-bit integer mod \\( -//! \ell \\), use +//! There is also a constructor that reduces a \\(512\\)-bit integer, //! [`Scalar::from_bytes_mod_order_wide`](struct.Scalar.html#method.from_bytes_mod_order_wide). -//! This is most frequently used to produce a `Scalar` from the output of a -//! 512-bit hash function: +//! +//! To construct a `Scalar` as the hash of some input data, use +//! [`Scalar::hash_from_bytes`](struct.Scalar.html#method.hash_from_bytes), +//! which takes a buffer, or +//! [`Scalar::from_hash`](struct.Scalar.html#method.from_hash), +//! which allows an IUF API. //! //! ``` //! # extern crate curve25519_dalek; -//! # extern crate digest; //! # extern crate sha2; //! # //! # fn main() { +//! use sha2::{Digest, Sha512}; //! use curve25519_dalek::scalar::Scalar; //! -//! use digest::Input; +//! // Hashing a single byte slice +//! let a = Scalar::hash_from_bytes::(b"Abolish ICE"); //! -//! use sha2::Digest; -//! use sha2::Sha512; +//! // Streaming data into a hash object +//! let mut hasher = Sha512::default(); +//! hasher.input(b"Abolish "); +//! hasher.input(b"ICE"); +//! let a2 = Scalar::from_hash(hasher); //! -//! let mut hasher: Sha512 = Sha512::default(); -//! let mut hash: [u8; 64] = [0u8; 64]; -//! -//! hasher.input(b"Abolish ICE"); -//! hash.copy_from_slice(hasher.result().as_slice()); -//! -//! let a: Scalar = Scalar::from_bytes_mod_order_wide(&hash); +//! assert_eq!(a, a2); //! # } //! ``` //! -//! However, for hashes in particular, there are also the convenience methods -//! [`Scalar::from_hash`](struct.Scalar.html#method.from_hash) and -//! [`Scalar::hash_from_bytes`](struct.Scalar.html#method.hash_from_bytes). -//! -//! To create a `Scalar` with a specific bit-pattern (e.g., for compatibility -//! with X25519 +//! Finally, to create a `Scalar` with a specific bit-pattern +//! (e.g., for compatibility with X/Ed25519 //! ["clamping"](https://github.com/isislovecruft/ed25519-dalek/blob/f790bd2ce/src/ed25519.rs#L349)), //! use [`Scalar::from_bits`](struct.Scalar.html#method.from_bits). This //! constructs a scalar with exactly the bit pattern given, without any @@ -136,9 +135,8 @@ //! assert!(a.reduce() == two); // if we were to reduce it manually, it would be. //! ``` //! -//! In particular, the bit pattern for the resulting scalar is invariant, -//! **except for the high bit, which will be unset** in order to preserve the -//! condition that scalars are 255-bit integers. +//! The resulting `Scalar` has exactly the specified bit pattern, +//! **except for the highest bit, which will be set to 0**. use core::fmt::Debug; use core::ops::Neg; From 0ab60b93eec13bb42d0989d7cd1459f3a810d2eb Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Jul 2018 13:34:02 -0700 Subject: [PATCH 12/14] Update wording on Scalar::invert to use self --- src/scalar.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scalar.rs b/src/scalar.rs index 705034f..77704af 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -522,11 +522,11 @@ impl Scalar { Scalar{ bytes: s_bytes } } - /// Compute the multiplicative inverse of this scalar. + /// Given a nonzero `Scalar`, compute its multiplicative inverse. /// /// # Warning /// - /// All input `Scalars` **MUST** be nonzero. If you cannot + /// `self` **MUST** be nonzero. If you cannot /// *prove* that this is the case, you **SHOULD NOT USE THIS /// FUNCTION**. /// From 5b009a033e3419f833b89d34a8bda64ebde879e3 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Jul 2018 13:34:14 -0700 Subject: [PATCH 13/14] Remove extra line in doctest --- src/scalar.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/scalar.rs b/src/scalar.rs index 77704af..945691c 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -584,7 +584,6 @@ impl Scalar { /// # extern crate curve25519_dalek; /// # use curve25519_dalek::scalar::Scalar; /// # fn main() { - /// /// let mut scalars = [ /// Scalar::from_u64(3), /// Scalar::from_u64(5), From fa904c2c420a1909044ef40b90cdde0913c1051f Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 5 Jul 2018 13:39:29 -0700 Subject: [PATCH 14/14] Add note on backend selection requirement --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4f09ba5..4c7353c 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,6 @@ extern crate curve25519_dalek; # Backends and Features -The `std` feature is enabled by default, but it can be disabled. - The `nightly` feature enables features available only when using a Rust nightly compiler. **It is recommended for security**. @@ -80,6 +78,11 @@ cargo build --no-default-features --features "std avx2_backend" Crates using `curve25519-dalek` can either select a backend on behalf of their users, or expose feature flags that control the `curve25519-dalek` backend. +The `std` feature is enabled by default, but it can be disabled for no-`std` +builds using `--no-default-features`. Note that this requires explicitly +selecting an arithmetic backend using one of the `_backend` features. +If no backend is selected, compilation will fail. + Benchmarks are run using [`criterion.rs`][criterion]: ```sh