2016-12-08 05:12:00 +00:00
// -*- mode: rust; -*-
//
2017-08-15 05:09:20 +00:00
// This file is part of curve25519-dalek.
// Copyright (c) 2016-2017 Isis Lovecruft, Henry de Valence
2017-09-04 02:49:26 +00:00
// Portions Copyright 2017 Brian Smith
2017-08-15 05:09:20 +00:00
// See LICENSE for licensing information.
2016-12-08 05:12:00 +00:00
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
// - Henry de Valence <hdevalence@hdevalence.ca>
2017-09-04 02:49:26 +00:00
// - Brian Smith <brian@briansmith.org>
2016-12-08 05:12:00 +00:00
2017-12-01 00:43:21 +00:00
//! Arithmetic on scalars (integers mod the group order).
2018-07-04 21:29:36 +00:00
//!
//! 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 \\).
2016-12-08 05:12:00 +00:00
2017-02-23 11:15:55 +00:00
use core ::fmt ::Debug ;
2017-05-03 05:29:18 +00:00
use core ::ops ::Neg ;
use core ::ops ::{ Add , AddAssign } ;
use core ::ops ::{ Sub , SubAssign } ;
use core ::ops ::{ Mul , MulAssign } ;
2017-11-23 00:04:47 +00:00
use core ::ops ::{ Index } ;
2017-05-03 05:29:18 +00:00
use core ::cmp ::{ Eq , PartialEq } ;
2018-05-01 22:56:23 +00:00
use core ::iter ::{ Product , Sum } ;
2018-05-01 22:55:38 +00:00
use core ::borrow ::Borrow ;
2016-12-08 05:12:00 +00:00
2018-05-14 20:24:23 +00:00
use rand ::{ Rng , CryptoRng } ;
2016-12-10 01:24:43 +00:00
2017-02-27 19:19:06 +00:00
use digest ::Digest ;
use generic_array ::typenum ::U64 ;
2018-02-07 00:47:30 +00:00
use subtle ::Choice ;
2017-08-01 02:09:34 +00:00
use subtle ::ConditionallyAssignable ;
2018-02-07 00:47:30 +00:00
use subtle ::ConstantTimeEq ;
2016-12-08 05:12:00 +00:00
2017-11-17 00:07:55 +00:00
use backend ;
2017-11-21 19:28:25 +00:00
use constants ;
2017-11-17 00:07:55 +00:00
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
2018-01-31 02:19:53 +00:00
///
2017-11-23 00:04:47 +00:00
/// This is a type alias for one of the scalar types in the `backend`
/// module.
2018-05-15 00:35:34 +00:00
#[ cfg(feature = " u64_backend " ) ]
2017-11-17 00:07:55 +00:00
type UnpackedScalar = backend ::u64 ::scalar ::Scalar64 ;
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
2018-01-31 02:19:53 +00:00
///
2017-11-23 00:04:47 +00:00
/// This is a type alias for one of the scalar types in the `backend`
/// module.
2018-05-15 00:35:34 +00:00
#[ cfg(feature = " u32_backend " ) ]
2017-11-17 00:07:55 +00:00
type UnpackedScalar = backend ::u32 ::scalar ::Scalar32 ;
2017-12-01 00:43:21 +00:00
/// The `Scalar` struct holds an integer \\(s < 2\^{255} \\) which
/// represents an element of \\(\mathbb Z / \ell\\).
2017-02-21 01:46:01 +00:00
#[ derive(Copy, Clone) ]
2017-11-23 00:04:47 +00:00
pub struct Scalar {
/// `bytes` is a little-endian byte encoding of an integer representing a scalar modulo the group order.
2018-01-31 02:19:53 +00:00
///
2017-11-23 00:04:47 +00:00
/// # Invariant
2018-01-31 02:19:53 +00:00
///
2017-12-01 00:46:46 +00:00
/// The integer representing this scalar must be bounded above by \\(2\^{255}\\), or equivalently the high bit of `bytes[31]` must be zero.
2018-01-31 02:19:53 +00:00
///
2018-04-06 19:11:59 +00:00
/// This ensures that there is room for a carry bit when computing a NAF representation.
2017-11-23 00:04:47 +00:00
// 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 ] ,
}
impl Scalar {
2017-12-01 00:43:21 +00:00
/// Construct a `Scalar` by reducing a 256-bit little-endian integer
/// modulo the group order \\( \ell \\).
pub fn from_bytes_mod_order ( bytes : [ u8 ; 32 ] ) -> Scalar {
2017-11-23 00:04:47 +00:00
// Temporarily allow s_unreduced.bytes > 2^255 ...
let s_unreduced = Scalar { bytes : bytes } ;
// Then reduce mod the group order and return the reduced representative.
let s = s_unreduced . reduce ( ) ;
debug_assert_eq! ( 0 u8 , s [ 31 ] > > 7 ) ;
s
}
2017-12-01 00:44:10 +00:00
/// Construct a `Scalar` by reducing a 512-bit little-endian integer
/// modulo the group order \\( \ell \\).
pub fn from_bytes_mod_order_wide ( input : & [ u8 ; 64 ] ) -> Scalar {
UnpackedScalar ::from_bytes_wide ( input ) . pack ( )
}
2017-11-23 00:45:16 +00:00
/// Attempt to construct a `Scalar` from a canonical byte representation.
///
/// # Return
///
/// - `Some(s)`, where `s` is the `Scalar` corresponding to `bytes`,
/// if `bytes` is a canonical byte representation;
/// - `None` if `bytes` is not a canonical byte representation.
pub fn from_canonical_bytes ( bytes : [ u8 ; 32 ] ) -> Option < Scalar > {
// Check that the high bit is not set
if ( bytes [ 31 ] > > 7 ) ! = 0 u8 { return None ; }
let candidate = Scalar ::from_bits ( bytes ) ;
if candidate . is_canonical ( ) {
Some ( candidate )
} else {
None
}
}
2017-11-23 00:04:47 +00:00
/// Construct a `Scalar` from the low 255 bits of a 256-bit integer.
2018-01-31 02:19:53 +00:00
///
2017-11-23 00:04:47 +00:00
/// This function is intended for applications like X25519 which
/// require specific bit-patterns when performing scalar
/// multiplication.
pub fn from_bits ( bytes : [ u8 ; 32 ] ) -> Scalar {
let mut s = Scalar { bytes : bytes } ;
// Ensure that s < 2^255 by masking the high bit
s . bytes [ 31 ] & = 0b0111_1111 ;
s
}
}
2016-12-08 05:12:00 +00:00
2017-02-23 11:15:55 +00:00
impl Debug for Scalar {
fn fmt ( & self , f : & mut ::core ::fmt ::Formatter ) -> ::core ::fmt ::Result {
2017-11-23 00:04:47 +00:00
write! ( f , " Scalar{{ \n \t bytes: {:?}, \n }} " , & self . bytes )
2017-02-23 11:15:55 +00:00
}
}
2017-05-28 22:42:09 +00:00
impl Eq for Scalar { }
2017-01-06 19:39:55 +00:00
impl PartialEq for Scalar {
fn eq ( & self , other : & Self ) -> bool {
2018-02-07 00:47:30 +00:00
self . ct_eq ( other ) . unwrap_u8 ( ) = = 1 u8
2017-01-06 19:39:55 +00:00
}
}
2018-02-07 00:47:30 +00:00
impl ConstantTimeEq for Scalar {
fn ct_eq ( & self , other : & Self ) -> Choice {
self . bytes . ct_eq ( & other . bytes )
2017-02-21 02:14:31 +00:00
}
}
2016-12-08 05:12:00 +00:00
impl Index < usize > for Scalar {
type Output = u8 ;
2017-11-23 00:04:47 +00:00
/// Index the bytes of the representative for this `Scalar`. Mutation is not permitted.
2017-04-02 21:36:05 +00:00
fn index ( & self , _index : usize ) -> & u8 {
2017-11-23 00:04:47 +00:00
& ( self . bytes [ _index ] )
2016-12-08 05:12:00 +00:00
}
}
2017-05-03 05:29:18 +00:00
impl < ' b > MulAssign < & ' b Scalar > for Scalar {
fn mul_assign ( & mut self , _rhs : & ' b Scalar ) {
2017-11-21 18:43:49 +00:00
* self = UnpackedScalar ::mul ( & self . unpack ( ) , & _rhs . unpack ( ) ) . pack ( ) ;
2017-05-03 05:29:18 +00:00
}
}
2018-01-24 18:58:22 +00:00
define_mul_assign_variants! ( LHS = Scalar , RHS = Scalar ) ;
2017-05-03 05:29:18 +00:00
impl < ' a , ' b > Mul < & ' b Scalar > for & ' a Scalar {
2017-01-06 17:08:37 +00:00
type Output = Scalar ;
2017-05-03 05:29:18 +00:00
fn mul ( self , _rhs : & ' b Scalar ) -> Scalar {
2017-11-21 18:43:49 +00:00
UnpackedScalar ::mul ( & self . unpack ( ) , & _rhs . unpack ( ) ) . pack ( )
2017-05-03 05:29:18 +00:00
}
}
2017-01-06 17:08:37 +00:00
2018-01-24 18:58:22 +00:00
define_mul_variants! ( LHS = Scalar , RHS = Scalar , Output = Scalar ) ;
2017-05-03 05:29:18 +00:00
impl < ' b > AddAssign < & ' b Scalar > for Scalar {
fn add_assign ( & mut self , _rhs : & ' b Scalar ) {
2017-11-21 18:43:49 +00:00
* self = UnpackedScalar ::add ( & self . unpack ( ) , & _rhs . unpack ( ) ) . pack ( ) ;
2017-05-03 05:29:18 +00:00
}
}
2018-01-24 18:58:22 +00:00
define_add_assign_variants! ( LHS = Scalar , RHS = Scalar ) ;
2017-05-03 05:29:18 +00:00
impl < ' a , ' b > Add < & ' b Scalar > for & ' a Scalar {
type Output = Scalar ;
fn add ( self , _rhs : & ' b Scalar ) -> Scalar {
2017-11-21 18:43:49 +00:00
UnpackedScalar ::add ( & self . unpack ( ) , & _rhs . unpack ( ) ) . pack ( )
2017-05-03 05:29:18 +00:00
}
}
2018-01-24 18:58:22 +00:00
define_add_variants! ( LHS = Scalar , RHS = Scalar , Output = Scalar ) ;
2017-05-03 05:29:18 +00:00
impl < ' b > SubAssign < & ' b Scalar > for Scalar {
fn sub_assign ( & mut self , _rhs : & ' b Scalar ) {
2017-11-21 18:43:49 +00:00
* self = UnpackedScalar ::sub ( & self . unpack ( ) , & _rhs . unpack ( ) ) . pack ( ) ;
2017-01-06 17:08:37 +00:00
}
}
2018-01-24 18:58:22 +00:00
define_sub_assign_variants! ( LHS = Scalar , RHS = Scalar ) ;
2017-05-03 05:29:18 +00:00
impl < ' a , ' b > Sub < & ' b Scalar > for & ' a Scalar {
type Output = Scalar ;
fn sub ( self , _rhs : & ' b Scalar ) -> Scalar {
2017-11-21 18:43:49 +00:00
UnpackedScalar ::sub ( & self . unpack ( ) , & _rhs . unpack ( ) ) . pack ( )
2017-01-06 17:08:37 +00:00
}
}
2018-01-24 18:58:22 +00:00
define_sub_variants! ( LHS = Scalar , RHS = Scalar , Output = Scalar ) ;
2017-05-03 05:29:18 +00:00
impl < ' a > Neg for & ' a Scalar {
type Output = Scalar ;
fn neg ( self ) -> Scalar {
2017-11-21 18:43:49 +00:00
& Scalar ::zero ( ) - self
2017-05-28 22:42:09 +00:00
}
2017-05-03 05:29:18 +00:00
}
2018-01-24 18:58:22 +00:00
impl < ' a > Neg for Scalar {
type Output = Scalar ;
fn neg ( self ) -> Scalar {
- & self
}
}
2017-08-01 02:09:34 +00:00
impl ConditionallyAssignable for Scalar {
2018-02-07 00:47:30 +00:00
fn conditional_assign ( & mut self , other : & Scalar , choice : Choice ) {
2017-01-06 17:56:53 +00:00
for i in 0 .. 32 {
2018-02-07 00:47:30 +00:00
self . bytes [ i ] . conditional_assign ( & other . bytes [ i ] , choice ) ;
2017-01-06 17:56:53 +00:00
}
}
}
2017-05-15 09:54:40 +00:00
#[ cfg(feature = " serde " ) ]
use serde ::{ self , Serialize , Deserialize , Serializer , Deserializer } ;
#[ cfg(feature = " serde " ) ]
use serde ::de ::Visitor ;
#[ cfg(feature = " serde " ) ]
impl Serialize for Scalar {
fn serialize < S > ( & self , serializer : S ) -> Result < S ::Ok , S ::Error >
where S : Serializer
{
2017-11-23 01:01:44 +00:00
serializer . serialize_bytes ( self . reduce ( ) . as_bytes ( ) )
2017-05-15 09:54:40 +00:00
}
}
#[ cfg(feature = " serde " ) ]
impl < ' de > Deserialize < ' de > for Scalar {
fn deserialize < D > ( deserializer : D ) -> Result < Self , D ::Error >
where D : Deserializer < ' de >
{
struct ScalarVisitor ;
impl < ' de > Visitor < ' de > for ScalarVisitor {
type Value = Scalar ;
fn expecting ( & self , formatter : & mut ::core ::fmt ::Formatter ) -> ::core ::fmt ::Result {
2017-11-23 01:01:44 +00:00
formatter . write_str ( " a canonically-encoded 32-byte scalar value " )
2017-05-15 09:54:40 +00:00
}
fn visit_bytes < E > ( self , v : & [ u8 ] ) -> Result < Scalar , E >
where E : serde ::de ::Error
{
if v . len ( ) = = 32 {
2017-11-20 22:53:08 +00:00
let mut bytes = [ 0 u8 ; 32 ] ;
bytes . copy_from_slice ( v ) ;
2017-11-23 01:01:44 +00:00
static ERRMSG : & 'static str = " encoding was not canonical " ;
Scalar ::from_canonical_bytes ( bytes )
. ok_or (
serde ::de ::Error ::invalid_value (
serde ::de ::Unexpected ::Bytes ( v ) ,
& ERRMSG ,
)
)
2017-05-15 09:54:40 +00:00
} else {
Err ( serde ::de ::Error ::invalid_length ( v . len ( ) , & self ) )
}
}
}
deserializer . deserialize_bytes ( ScalarVisitor )
}
}
2018-05-01 22:55:38 +00:00
impl < T > Product < T > for Scalar
where
T : Borrow < Scalar >
{
fn product < I > ( iter : I ) -> Self
where
I : Iterator < Item = T >
{
iter . fold ( Scalar ::one ( ) , | acc , item | acc * item . borrow ( ) )
}
}
2018-05-01 22:56:23 +00:00
impl < T > Sum < T > for Scalar
where
T : Borrow < Scalar >
{
fn sum < I > ( iter : I ) -> Self
where
I : Iterator < Item = T >
{
iter . fold ( Scalar ::zero ( ) , | acc , item | acc + item . borrow ( ) )
}
}
2016-12-08 05:12:00 +00:00
impl Scalar {
2017-05-03 04:22:04 +00:00
/// Return a `Scalar` chosen uniformly at random using a user-provided RNG.
2016-12-14 05:38:06 +00:00
///
/// # Inputs
///
2018-05-14 20:24:23 +00:00
/// * `rng`: any RNG which implements the `rand::CryptoRng` interface.
2016-12-14 05:38:06 +00:00
///
/// # Returns
///
/// A random scalar within ℤ /lℤ .
2017-01-14 01:43:08 +00:00
#[ cfg(feature = " std " ) ]
2018-05-14 20:24:23 +00:00
pub fn random < T : Rng + CryptoRng > ( rng : & mut T ) -> Self {
2016-12-10 01:24:43 +00:00
let mut scalar_bytes = [ 0 u8 ; 64 ] ;
2018-05-14 20:24:23 +00:00
rng . fill ( & mut scalar_bytes ) ;
2017-12-01 00:44:10 +00:00
Scalar ::from_bytes_mod_order_wide ( & scalar_bytes )
2016-12-10 01:24:43 +00:00
}
2017-02-27 19:19:06 +00:00
/// Hash a slice of bytes into a scalar.
///
/// Takes a type parameter `D`, which is any `Digest` producing 64
/// bytes (512 bits) of output.
///
2017-03-01 03:08:37 +00:00
/// Convenience wrapper around `from_hash`.
///
2017-02-27 19:19:06 +00:00
/// # Example
///
/// ```
/// # extern crate curve25519_dalek;
/// # use curve25519_dalek::scalar::Scalar;
/// extern crate sha2;
/// use sha2::Sha512;
///
2017-02-27 19:22:07 +00:00
/// # // Need fn main() here in comment so the doctest compiles
/// # // See https://doc.rust-lang.org/book/documentation.html#documentation-as-tests
2017-02-27 19:19:06 +00:00
/// # fn main() {
/// let msg = "To really appreciate architecture, you may even need to commit a murder";
/// let s = Scalar::hash_from_bytes::<Sha512>(msg.as_bytes());
/// # }
/// ```
///
pub fn hash_from_bytes < D > ( input : & [ u8 ] ) -> Scalar
2017-05-28 22:42:09 +00:00
where D : Digest < OutputSize = U64 > + Default
{
2017-02-27 19:19:06 +00:00
let mut hash = D ::default ( ) ;
hash . input ( input ) ;
2017-03-01 03:08:37 +00:00
Scalar ::from_hash ( hash )
}
/// Construct a scalar from an existing `Digest` instance.
///
/// Use this instead of `hash_from_bytes` if it is more convenient
/// to stream data into the `Digest` than to pass a single byte
/// slice.
pub fn from_hash < D > ( hash : D ) -> Scalar
2017-05-28 22:42:09 +00:00
where D : Digest < OutputSize = U64 > + Default
{
2017-02-27 19:19:06 +00:00
// XXX this seems clumsy
2017-05-28 22:42:09 +00:00
let mut output = [ 0 u8 ; 64 ] ;
2017-02-27 19:19:06 +00:00
output . copy_from_slice ( hash . result ( ) . as_slice ( ) ) ;
2017-12-01 00:44:10 +00:00
Scalar ::from_bytes_mod_order_wide ( & output )
2017-02-27 19:19:06 +00:00
}
2017-11-26 03:23:31 +00:00
/// Convert this `Scalar` to its underlying sequence of bytes.
pub fn to_bytes ( & self ) -> [ u8 ; 32 ] {
2017-11-26 04:16:12 +00:00
self . bytes
2017-11-26 03:23:31 +00:00
}
2017-02-23 11:26:57 +00:00
/// View this `Scalar` as a sequence of bytes.
2017-05-06 00:16:09 +00:00
pub fn as_bytes ( & self ) -> & [ u8 ; 32 ] {
2017-11-23 00:04:47 +00:00
& self . bytes
2017-02-23 11:26:57 +00:00
}
2017-12-01 00:43:21 +00:00
/// Construct the scalar \\( 0 \\).
2016-12-08 05:12:00 +00:00
pub fn zero ( ) -> Self {
2017-11-23 00:04:47 +00:00
Scalar { bytes : [ 0 u8 ; 32 ] }
2016-12-08 05:12:00 +00:00
}
2017-12-01 00:43:21 +00:00
/// Construct the scalar \\( 1 \\).
2016-12-08 05:12:00 +00:00
pub fn one ( ) -> Self {
2017-11-23 00:04:47 +00:00
Scalar {
bytes : [
1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
] ,
}
2016-12-08 05:12:00 +00:00
}
2017-05-04 02:06:41 +00:00
/// Construct a scalar from the given `u64`.
pub fn from_u64 ( x : u64 ) -> Scalar {
2017-11-23 00:04:47 +00:00
let mut s_bytes = [ 0 u8 ; 32 ] ;
2017-05-04 02:06:41 +00:00
for i in 0 .. 8 {
2017-11-23 00:04:47 +00:00
s_bytes [ i ] = ( x > > ( i * 8 ) ) as u8 ;
2017-05-04 02:06:41 +00:00
}
2017-11-23 00:04:47 +00:00
Scalar { bytes : s_bytes }
2017-05-04 02:06:41 +00:00
}
2017-04-29 05:59:56 +00:00
/// Compute the multiplicative inverse of this scalar.
pub fn invert ( & self ) -> Scalar {
self . unpack ( ) . invert ( ) . pack ( )
}
2018-03-19 21:03:27 +00:00
/// Given a slice of nonzero (possibly secret) `Scalar`s,
/// compute their inverses in a batch.
///
/// # Return
///
/// Each element of `inputs` is replaced by its inverse.
///
/// The product of all inverses is returned.
///
/// # Warning
///
/// All input `Scalars` **MUST** be nonzero. If you cannot
/// *prove* that this is the case, you **SHOULD NOT USE THIS
/// FUNCTION**.
///
/// # Example
///
/// ```
/// # extern crate curve25519_dalek;
/// # use curve25519_dalek::scalar::Scalar;
/// # fn main() {
///
/// let mut scalars = [
/// Scalar::from_u64(3),
/// Scalar::from_u64(5),
/// Scalar::from_u64(7),
/// Scalar::from_u64(11),
/// ];
///
/// let allinv = Scalar::batch_invert(&mut scalars);
///
/// assert_eq!(allinv, Scalar::from_u64(3*5*7*11).invert());
/// assert_eq!(scalars[0], Scalar::from_u64(3).invert());
/// assert_eq!(scalars[1], Scalar::from_u64(5).invert());
/// assert_eq!(scalars[2], Scalar::from_u64(7).invert());
/// assert_eq!(scalars[3], Scalar::from_u64(11).invert());
/// # }
/// ```
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
pub fn batch_invert ( inputs : & mut [ Scalar ] ) -> Scalar {
// This code is essentially identical to the FieldElement
// implementation, and is documented there. Unfortunately,
// it's not easy to write it generically, since here we want
// to use `UnpackedScalar`s internally, and `Scalar`s
// externally, but there's no corresponding distinction for
// field elements.
use clear_on_drop ::ClearOnDrop ;
use clear_on_drop ::clear ::ZeroSafe ;
// Mark UnpackedScalars as zeroable.
unsafe impl ZeroSafe for UnpackedScalar { }
2018-06-30 22:30:35 +00:00
let n = inputs . len ( ) ;
2018-03-19 21:03:27 +00:00
let one : UnpackedScalar = Scalar ::one ( ) . unpack ( ) . to_montgomery ( ) ;
2018-06-30 22:30:35 +00:00
// Wrap the scratch storage in a ClearOnDrop to wipe it when
// we pass out of scope.
let scratch_vec = vec! [ one ; n ] ;
let mut scratch = ClearOnDrop ::new ( scratch_vec ) ;
2018-03-19 21:03:27 +00:00
2018-06-30 22:30:35 +00:00
// Keep an accumulator of all of the previous products
let mut acc = Scalar ::one ( ) . unpack ( ) . to_montgomery ( ) ;
// Pass through the input vector, recording the previous
// products in the scratch space
for ( input , scratch ) in inputs . iter_mut ( ) . zip ( scratch . iter_mut ( ) ) {
* scratch = acc ;
2018-03-19 21:03:27 +00:00
2018-06-30 22:30:35 +00:00
// Avoid unnecessary Montgomery multiplication in second pass by
// keeping inputs in Montgomery form
let tmp = input . unpack ( ) . to_montgomery ( ) ;
* input = tmp . pack ( ) ;
acc = UnpackedScalar ::montgomery_mul ( & acc , & tmp ) ;
2018-03-19 21:03:27 +00:00
}
2018-06-30 22:30:35 +00:00
// acc is nonzero iff all inputs are nonzero
debug_assert! ( acc . pack ( ) ! = Scalar ::zero ( ) ) ;
2018-03-22 18:31:14 +00:00
2018-06-30 22:30:35 +00:00
// Compute the inverse of all products
acc = acc . montgomery_invert ( ) . from_montgomery ( ) ;
2018-03-19 21:03:27 +00:00
2018-06-30 22:30:35 +00:00
// We need to return the product of all inverses later
let ret = acc . pack ( ) ;
// Pass through the vector backwards to compute the inverses
// in place
for ( input , scratch ) in inputs . iter_mut ( ) . rev ( ) . zip ( scratch . into_iter ( ) . rev ( ) ) {
let tmp = UnpackedScalar ::montgomery_mul ( & acc , & input . unpack ( ) ) ;
* input = UnpackedScalar ::montgomery_mul ( & acc , & scratch ) . pack ( ) ;
acc = tmp ;
2018-03-19 21:03:27 +00:00
}
2018-06-30 22:30:35 +00:00
ret
2018-03-19 21:03:27 +00:00
}
2017-04-29 05:51:32 +00:00
/// Get the bits of the scalar.
2017-11-21 00:45:30 +00:00
pub ( crate ) fn bits ( & self ) -> [ i8 ; 256 ] {
2017-04-29 05:51:32 +00:00
let mut bits = [ 0 i8 ; 256 ] ;
for i in 0 .. 256 {
// As i runs from 0..256, the bottom 3 bits index the bit,
// while the upper bits index the byte.
2017-11-23 00:04:47 +00:00
bits [ i ] = ( ( self . bytes [ i > > 3 ] > > ( i & 7 ) ) & 1 u8 ) as i8 ;
2017-04-29 05:51:32 +00:00
}
bits
}
2018-04-05 04:13:09 +00:00
/// Compute a width-\\(w\\) "Non-Adjacent Form" of this scalar.
2016-12-08 05:12:00 +00:00
///
2017-12-01 00:43:21 +00:00
/// A width-\\(w\\) NAF of a positive integer \\(k\\) is an expression
/// $$
2018-04-06 19:11:59 +00:00
/// k = \sum_{i=0}\^m n\_i 2\^i,
2017-12-01 00:43:21 +00:00
/// $$
/// where each nonzero
2018-04-06 19:11:59 +00:00
/// coefficient \\(n\_i\\) is odd and bounded by \\(|n\_i| < 2\^{w-1}\\),
/// \\(n\_{m-1}\\) is nonzero, and at most one of any \\(w\\) consecutive
2016-12-08 05:12:00 +00:00
/// coefficients is nonzero. (Hankerson, Menezes, Vanstone; def 3.32).
///
2018-04-06 19:11:59 +00:00
/// The length of the NAF is at most one more than the length of
/// the binary representation of \\(k\\). This is why the
/// `Scalar` type maintains an invariant that the top bit is
/// \\(0\\), so that the NAF of a scalar has at most 256 digits.
///
2016-12-08 05:12:00 +00:00
/// Intuitively, this is like a binary expansion, except that we
2018-04-06 19:11:59 +00:00
/// allow some coefficients to grow in magnitude up to
/// \\(2\^{w-1}\\) so that the nonzero coefficients are as sparse
/// as possible.
///
/// When doing scalar multiplication, we can then use a lookup
/// table of precomputed multiples of a point to add the nonzero
/// terms \\( k_i P \\). Using signed digits cuts the table size
/// in half, and using odd digits cuts the table size in half
/// again.
///
/// To compute a \\(w\\)-NAF, we use a modification of Algorithm 3.35 of HMV:
///
/// 1. \\( i \gets 0 \\)
/// 2. While \\( k \ge 1 \\):
/// 1. If \\(k\\) is odd, \\( n_i \gets k \operatorname{mods} 2^w \\), \\( k \gets k - n_i \\).
/// 2. If \\(k\\) is even, \\( n_i \gets 0 \\).
/// 3. \\( k \gets k / 2 \\), \\( i \gets i + 1 \\).
/// 3. Return \\( n_0, n_1, ... , \\)
///
/// Here \\( \bar x = x \operatorname{mods} 2^w \\) means the
/// \\( \bar x \\) with \\( \bar x \equiv x \pmod{2^w} \\) and
/// \\( -2^{w-1} \leq \bar x < 2^w \\).
///
2018-04-08 23:29:54 +00:00
/// We implement this by scanning across the bits of \\(k\\) from
/// least-significant bit to most-significant-bit.
2018-04-06 19:11:59 +00:00
/// Write the bits of \\(k\\) as
/// $$
/// k = \sum\_{i=0}\^m k\_i 2^i,
/// $$
2018-05-01 22:57:24 +00:00
/// and split the sum as
2018-04-06 19:11:59 +00:00
/// $$
/// k = \sum\_{i=0}^{w-1} k\_i 2^i + 2^w \sum\_{i=0} k\_{i+w} 2^i
/// $$
/// where the first part is \\( k \mod 2^w \\).
///
/// If \\( k \mod 2^w\\) is odd, and \\( k \mod 2^w < 2^{w-1} \\), then we emit
/// \\( n_0 = k \mod 2^w \\). Instead of computing
/// \\( k - n_0 \\), we just advance \\(w\\) bits and reindex.
///
/// If \\( k \mod 2^w\\) is odd, and \\( k \mod 2^w \ge 2^{w-1} \\), then
/// \\( n_0 = k \operatorname{mods} 2^w = k \mod 2^w - 2^w \\).
/// The quantity \\( k - n_0 \\) is
/// $$
/// \begin{aligned}
/// k - n_0 &= \sum\_{i=0}^{w-1} k\_i 2^i + 2^w \sum\_{i=0} k\_{i+w} 2^i
/// - \sum\_{i=0}^{w-1} k\_i 2^i + 2^w \\\\
/// &= 2^w + 2^w \sum\_{i=0} k\_{i+w} 2^i
/// \end{aligned}
/// $$
/// so instead of computing the subtraction, we can set a carry
/// bit, advance \\(w\\) bits, and reindex.
///
/// If \\( k \mod 2^w\\) is even, we emit \\(0\\), advance 1 bit
/// and reindex. In fact, by setting all digits to \\(0\\)
/// initially, we don't need to emit anything.
2018-04-05 04:13:09 +00:00
pub ( crate ) fn non_adjacent_form ( & self , w : usize ) -> [ i8 ; 256 ] {
2018-04-06 19:11:59 +00:00
// required by the NAF definition
debug_assert! ( w > = 2 ) ;
// required so that the NAF digits fit in i8
debug_assert! ( w < = 8 ) ;
2018-04-05 04:13:09 +00:00
use byteorder ::{ ByteOrder , LittleEndian } ;
let mut naf = [ 0 i8 ; 256 ] ;
let mut x_u64 = [ 0 u64 ; 5 ] ;
LittleEndian ::read_u64_into ( & self . bytes , & mut x_u64 [ 0 .. 4 ] ) ;
let width = 1 < < w ;
let window_mask = width - 1 ;
2018-05-01 22:57:24 +00:00
2018-04-05 04:13:09 +00:00
let mut pos = 0 ;
let mut carry = 0 ;
while pos < 256 {
// Construct a buffer of bits of the scalar, starting at bit `pos`
let u64_idx = pos / 64 ;
let bit_idx = pos % 64 ;
let bit_buf : u64 ;
if bit_idx < 64 - w {
// This window's bits are contained in a single u64
bit_buf = x_u64 [ u64_idx ] > > bit_idx ;
} else {
// Combine the current u64's bits with the bits from the next u64
bit_buf = ( x_u64 [ u64_idx ] > > bit_idx ) | ( x_u64 [ 1 + u64_idx ] < < ( 64 - bit_idx ) ) ;
}
// Add the carry into the current window
let window = carry + ( bit_buf & window_mask ) ;
if window & 1 = = 0 {
// If the window value is even, preserve the carry and continue.
// Why is the carry preserved?
// If carry == 0 and window & 1 == 0, then the next carry should be 0
// If carry == 1 and window & 1 == 0, then bit_buf & 1 == 1 so the next carry should be 1
pos + = 1 ;
continue ;
2016-12-08 05:12:00 +00:00
}
2018-04-05 04:13:09 +00:00
if window < width / 2 {
carry = 0 ;
naf [ pos ] = window as i8 ;
} else {
carry = 1 ;
naf [ pos ] = ( window as i8 ) - ( width as i8 ) ;
}
pos + = w ;
2016-12-08 05:12:00 +00:00
}
naf
}
2017-12-01 00:43:21 +00:00
/// Write this scalar in radix 16, with coefficients in \\([-8,8)\\),
/// i.e., compute \\(a\_i\\) such that
/// $$
/// a = a\_0 + a\_1 16\^1 + \cdots + a_{63} 16\^{63},
/// $$
2018-04-06 19:11:59 +00:00
/// with \\(-8 \leq a_i < 8\\) for \\(0 \leq i < 63\\) and \\(-8 \leq a_{63} \leq 8\\).
2017-11-21 00:45:30 +00:00
pub ( crate ) fn to_radix_16 ( & self ) -> [ i8 ; 64 ] {
2016-12-08 05:12:00 +00:00
debug_assert! ( self [ 31 ] < = 127 ) ;
let mut output = [ 0 i8 ; 64 ] ;
// Step 1: change radix.
// Convert from radix 256 (bytes) to radix 16 (nibbles)
#[ inline(always) ]
fn bot_half ( x : u8 ) -> u8 { ( x > > 0 ) & 15 }
#[ inline(always) ]
fn top_half ( x : u8 ) -> u8 { ( x > > 4 ) & 15 }
for i in 0 .. 32 {
output [ 2 * i ] = bot_half ( self [ i ] ) as i8 ;
output [ 2 * i + 1 ] = top_half ( self [ i ] ) as i8 ;
}
// Precondition note: since self[31] <= 127, output[63] <= 7
// Step 2: recenter coefficients from [0,16) to [-8,8)
for i in 0 .. 63 {
let carry = ( output [ i ] + 8 ) > > 4 ;
output [ i ] - = carry < < 4 ;
output [ i + 1 ] + = carry ;
}
// Precondition note: output[63] is not recentered. It
// increases by carry <= 1. Thus output[63] <= 8.
output
}
2017-12-01 00:43:21 +00:00
/// Unpack this `Scalar` to an `UnpackedScalar` for faster arithmetic.
2017-11-17 23:51:29 +00:00
pub ( crate ) fn unpack ( & self ) -> UnpackedScalar {
2017-11-23 00:04:47 +00:00
UnpackedScalar ::from_bytes ( & self . bytes )
2016-12-23 20:49:00 +00:00
}
2017-12-01 00:43:21 +00:00
/// Reduce this `Scalar` modulo \\(\ell\\).
2018-03-19 21:03:27 +00:00
#[ allow(non_snake_case) ]
2017-11-21 19:28:25 +00:00
pub fn reduce ( & self ) -> Scalar {
let x = self . unpack ( ) ;
let xR = UnpackedScalar ::mul_internal ( & x , & constants ::R ) ;
let x_mod_l = UnpackedScalar ::montgomery_reduce ( & xR ) ;
x_mod_l . pack ( )
2017-10-30 19:27:44 +00:00
}
2017-10-16 21:41:52 +00:00
2018-01-31 02:19:53 +00:00
/// Check whether this `Scalar` is the canonical representative mod \\(\ell\\).
2017-11-23 00:23:32 +00:00
///
/// This is intended for uses like input validation, where variable-time code is acceptable.
///
/// ```
/// # extern crate curve25519_dalek;
/// # extern crate subtle;
/// # use curve25519_dalek::scalar::Scalar;
/// # use subtle::ConditionallyAssignable;
/// # fn main() {
/// // 2^255 - 1, since `from_bits` clears the high bit
/// let _2_255_minus_1 = Scalar::from_bits([0xff;32]);
/// assert!(!_2_255_minus_1.is_canonical());
///
/// let reduced = _2_255_minus_1.reduce();
/// assert!(reduced.is_canonical());
/// # }
/// ```
pub fn is_canonical ( & self ) -> bool {
* self = = self . reduce ( )
2016-12-23 20:49:00 +00:00
}
}
impl UnpackedScalar {
/// Pack the limbs of this `UnpackedScalar` into a `Scalar`.
fn pack ( & self ) -> Scalar {
2017-11-23 00:04:47 +00:00
Scalar { bytes : self . to_bytes ( ) }
2017-04-29 05:57:17 +00:00
}
2018-03-19 21:03:27 +00:00
/// Inverts an UnpackedScalar in Montgomery form.
pub fn montgomery_invert ( & self ) -> UnpackedScalar {
// Uses the addition chain from
2017-09-04 02:49:26 +00:00
// https://briansmith.org/ecc-inversion-addition-chains-01#curve25519_scalar_inversion
2018-03-19 21:03:27 +00:00
let _1 = self ;
2017-10-30 19:27:44 +00:00
let _10 = _1 . montgomery_square ( ) ;
let _100 = _10 . montgomery_square ( ) ;
let _11 = UnpackedScalar ::montgomery_mul ( & _10 , & _1 ) ;
let _101 = UnpackedScalar ::montgomery_mul ( & _10 , & _11 ) ;
let _111 = UnpackedScalar ::montgomery_mul ( & _10 , & _101 ) ;
let _1001 = UnpackedScalar ::montgomery_mul ( & _10 , & _111 ) ;
let _1011 = UnpackedScalar ::montgomery_mul ( & _10 , & _1001 ) ;
let _1111 = UnpackedScalar ::montgomery_mul ( & _100 , & _1011 ) ;
2017-09-04 19:19:58 +00:00
// _10000
2017-10-30 19:27:44 +00:00
let mut y = UnpackedScalar ::montgomery_mul ( & _1111 , & _1 ) ;
2017-09-04 02:49:26 +00:00
#[ inline ]
fn square_multiply ( y : & mut UnpackedScalar , squarings : usize , x : & UnpackedScalar ) {
for _ in 0 .. squarings {
2017-10-30 19:27:44 +00:00
* y = y . montgomery_square ( ) ;
2017-04-29 05:59:56 +00:00
}
2017-10-30 19:27:44 +00:00
* y = UnpackedScalar ::montgomery_mul ( y , x ) ;
2017-04-29 05:59:56 +00:00
}
2017-09-04 02:49:26 +00:00
square_multiply ( & mut y , 123 + 3 , & _101 ) ;
square_multiply ( & mut y , 2 + 2 , & _11 ) ;
square_multiply ( & mut y , 1 + 4 , & _1111 ) ;
square_multiply ( & mut y , 1 + 4 , & _1111 ) ;
square_multiply ( & mut y , 4 , & _1001 ) ;
2017-09-04 19:34:04 +00:00
square_multiply ( & mut y , 2 , & _11 ) ;
square_multiply ( & mut y , 1 + 4 , & _1111 ) ;
2017-09-04 02:49:26 +00:00
square_multiply ( & mut y , 1 + 3 , & _101 ) ;
square_multiply ( & mut y , 3 + 3 , & _101 ) ;
square_multiply ( & mut y , 3 , & _111 ) ;
square_multiply ( & mut y , 1 + 4 , & _1111 ) ;
square_multiply ( & mut y , 2 + 3 , & _111 ) ;
square_multiply ( & mut y , 2 + 2 , & _11 ) ;
square_multiply ( & mut y , 1 + 4 , & _1011 ) ;
square_multiply ( & mut y , 2 + 4 , & _1011 ) ;
square_multiply ( & mut y , 6 + 4 , & _1001 ) ;
square_multiply ( & mut y , 2 + 2 , & _11 ) ;
square_multiply ( & mut y , 3 + 2 , & _11 ) ;
square_multiply ( & mut y , 3 + 2 , & _11 ) ;
square_multiply ( & mut y , 1 + 4 , & _1001 ) ;
square_multiply ( & mut y , 1 + 3 , & _111 ) ;
square_multiply ( & mut y , 2 + 4 , & _1111 ) ;
square_multiply ( & mut y , 1 + 4 , & _1011 ) ;
square_multiply ( & mut y , 3 , & _101 ) ;
square_multiply ( & mut y , 2 + 4 , & _1111 ) ;
square_multiply ( & mut y , 3 , & _101 ) ;
square_multiply ( & mut y , 1 + 2 , & _11 ) ;
2018-03-19 21:03:27 +00:00
y
}
/// Inverts an UnpackedScalar not in Montgomery form.
pub fn invert ( & self ) -> UnpackedScalar {
self . to_montgomery ( ) . montgomery_invert ( ) . from_montgomery ( )
2016-12-08 05:12:00 +00:00
}
}
#[ cfg(test) ]
mod test {
use super ::* ;
2017-10-30 19:27:44 +00:00
use constants ;
2016-12-23 21:01:16 +00:00
2016-12-08 05:12:00 +00:00
/// x = 2238329342913194256032495932344128051776374960164957527413114840482143558222
2017-11-23 00:04:47 +00:00
pub static X : Scalar = Scalar {
bytes : [
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 ,
] ,
} ;
2017-10-30 19:27:44 +00:00
/// 1/x = 6859937278830797291664592131120606308688036382723378951768035303146619657244
2017-11-23 00:04:47 +00:00
pub static XINV : Scalar = Scalar {
bytes : [
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 ,
] ,
} ;
2016-12-08 05:12:00 +00:00
/// y = 2592331292931086675770238855846338635550719849568364935475441891787804997264
2017-11-23 00:04:47 +00:00
pub static Y : Scalar = Scalar {
bytes : [
0x90 , 0x76 , 0x33 , 0xfe , 0x1c , 0x4b , 0x66 , 0xa4 ,
0xa2 , 0x8d , 0x2d , 0xd7 , 0x67 , 0x83 , 0x86 , 0xc3 ,
0x53 , 0xd0 , 0xde , 0x54 , 0x55 , 0xd4 , 0xfc , 0x9d ,
0xe8 , 0xef , 0x7a , 0xc3 , 0x1f , 0x35 , 0xbb , 0x05 ,
] ,
} ;
2016-12-08 05:12:00 +00:00
/// x*y = 5690045403673944803228348699031245560686958845067437804563560795922180092780
2017-11-23 00:04:47 +00:00
static X_TIMES_Y : Scalar = Scalar {
bytes : [
0x6c , 0x33 , 0x74 , 0xa1 , 0x89 , 0x4f , 0x62 , 0x21 ,
0x0a , 0xaa , 0x2f , 0xe1 , 0x86 , 0xa6 , 0xf9 , 0x2c ,
0xe0 , 0xaa , 0x75 , 0xc2 , 0x77 , 0x95 , 0x81 , 0xc2 ,
0x95 , 0xfc , 0x08 , 0x17 , 0x9a , 0x73 , 0x94 , 0x0c ,
] ,
} ;
2017-11-23 00:22:16 +00:00
/// sage: l = 2^252 + 27742317777372353535851937790883648493
/// sage: big = 2^256 - 1
/// sage: repr((big % l).digits(256))
static CANONICAL_2_256_MINUS_1 : Scalar = Scalar {
bytes : [
28 , 149 , 152 , 141 , 116 , 49 , 236 , 214 ,
112 , 207 , 125 , 115 , 244 , 91 , 239 , 198 ,
254 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
255 , 255 , 255 , 255 , 255 , 255 , 255 , 15 ,
] ,
} ;
2017-11-23 00:04:47 +00:00
static A_SCALAR : Scalar = Scalar {
bytes : [
0x1a , 0x0e , 0x97 , 0x8a , 0x90 , 0xf6 , 0x62 , 0x2d ,
0x37 , 0x47 , 0x02 , 0x3f , 0x8a , 0xd8 , 0x26 , 0x4d ,
0xa7 , 0x58 , 0xaa , 0x1b , 0x88 , 0xe0 , 0x40 , 0xd1 ,
0x58 , 0x9e , 0x7b , 0x7f , 0x23 , 0x76 , 0xef , 0x09 ,
] ,
} ;
2016-12-08 05:12:00 +00:00
2017-03-17 21:42:40 +00:00
static A_NAF : [ i8 ; 256 ] =
2016-12-08 05:12:00 +00:00
[ 0 , 13 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 7 , 0 , 0 , 0 , 0 , 0 , 0 , - 9 , 0 , 0 , 0 , 0 , - 11 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 1 ,
0 , 0 , 0 , 0 , 9 , 0 , 0 , 0 , 0 , - 5 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 11 , 0 , 0 , 0 , 0 , 11 , 0 , 0 , 0 , 0 , 0 ,
- 9 , 0 , 0 , 0 , 0 , 0 , - 3 , 0 , 0 , 0 , 0 , 9 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , - 1 , 0 , 0 , 0 , 0 , 0 , 9 , 0 ,
0 , 0 , 0 , - 15 , 0 , 0 , 0 , 0 , - 7 , 0 , 0 , 0 , 0 , - 9 , 0 , 0 , 0 , 0 , 0 , 5 , 0 , 0 , 0 , 0 , 13 , 0 , 0 , 0 , 0 , 0 , - 3 , 0 ,
0 , 0 , 0 , - 11 , 0 , 0 , 0 , 0 , - 7 , 0 , 0 , 0 , 0 , - 13 , 0 , 0 , 0 , 0 , 11 , 0 , 0 , 0 , 0 , - 9 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 ,
0 , 0 , 0 , - 15 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 7 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 5 , 0 , 0 , 0 , 0 , 0 , 13 , 0 , 0 , 0 ,
0 , 0 , 0 , 11 , 0 , 0 , 0 , 0 , 0 , 15 , 0 , 0 , 0 , 0 , 0 , - 9 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 7 ,
0 , 0 , 0 , 0 , 0 , - 15 , 0 , 0 , 0 , 0 , 0 , 15 , 0 , 0 , 0 , 0 , 15 , 0 , 0 , 0 , 0 , 15 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 ] ;
2017-10-30 22:22:34 +00:00
#[ test ]
fn fuzzer_testcase_reduction ( ) {
// LE bytes of 24519928653854221733733552434404946937899825954937634815
let a_bytes = [ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ;
// LE bytes of 4975441334397345751130612518500927154628011511324180036903450236863266160640
let b_bytes = [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 210 , 210 , 210 , 255 , 255 , 255 , 255 , 10 ] ;
// LE bytes of 6432735165214683820902750800207468552549813371247423777071615116673864412038
let c_bytes = [ 134 , 171 , 119 , 216 , 180 , 128 , 178 , 62 , 171 , 132 , 32 , 62 , 34 , 119 , 104 , 193 , 47 , 215 , 181 , 250 , 14 , 207 , 172 , 93 , 75 , 207 , 211 , 103 , 144 , 204 , 56 , 14 ] ;
2017-11-23 00:04:47 +00:00
let a = Scalar ::from_bytes_mod_order ( a_bytes ) ;
let b = Scalar ::from_bytes_mod_order ( b_bytes ) ;
let c = Scalar ::from_bytes_mod_order ( c_bytes ) ;
2017-10-30 22:22:34 +00:00
let mut tmp = [ 0 u8 ; 64 ] ;
// also_a = (a mod l)
tmp [ 0 .. 32 ] . copy_from_slice ( & a_bytes [ .. ] ) ;
2017-12-01 00:44:10 +00:00
let also_a = Scalar ::from_bytes_mod_order_wide ( & tmp ) ;
2017-10-30 22:22:34 +00:00
// also_b = (b mod l)
tmp [ 0 .. 32 ] . copy_from_slice ( & b_bytes [ .. ] ) ;
2017-12-01 00:44:10 +00:00
let also_b = Scalar ::from_bytes_mod_order_wide ( & tmp ) ;
2017-10-30 22:22:34 +00:00
let expected_c = & a * & b ;
let also_expected_c = & also_a * & also_b ;
assert_eq! ( c , expected_c ) ;
assert_eq! ( c , also_expected_c ) ;
}
2016-12-08 05:12:00 +00:00
#[ test ]
2017-03-14 01:58:39 +00:00
fn non_adjacent_form ( ) {
2018-04-05 04:13:09 +00:00
let naf = A_SCALAR . non_adjacent_form ( 5 ) ;
2016-12-08 05:12:00 +00:00
for i in 0 .. 256 {
assert_eq! ( naf [ i ] , A_NAF [ i ] ) ;
}
}
2017-05-04 02:06:41 +00:00
#[ test ]
fn from_unsigned ( ) {
let val = 0xdeadbeefdeadbeef ;
let s = Scalar ::from_u64 ( val ) ;
assert_eq! ( s [ 7 ] , 0xde ) ;
assert_eq! ( s [ 6 ] , 0xad ) ;
assert_eq! ( s [ 5 ] , 0xbe ) ;
assert_eq! ( s [ 4 ] , 0xef ) ;
assert_eq! ( s [ 3 ] , 0xde ) ;
assert_eq! ( s [ 2 ] , 0xad ) ;
assert_eq! ( s [ 1 ] , 0xbe ) ;
assert_eq! ( s [ 0 ] , 0xef ) ;
}
2016-12-08 05:12:00 +00:00
#[ test ]
2018-03-22 18:40:13 +00:00
fn scalar_mul_by_one ( ) {
2017-12-01 00:44:51 +00:00
let test_scalar = & X * & Scalar ::one ( ) ;
2016-12-08 05:12:00 +00:00
for i in 0 .. 32 {
assert! ( test_scalar [ i ] = = X [ i ] ) ;
}
}
#[ test ]
2017-05-03 05:29:18 +00:00
fn impl_add ( ) {
2017-11-23 00:04:47 +00:00
let two = Scalar ::from_u64 ( 2 ) ;
2017-05-03 05:29:18 +00:00
let one = Scalar ::one ( ) ;
let should_be_two = & one + & one ;
assert_eq! ( should_be_two , two ) ;
2017-04-29 05:57:17 +00:00
}
2016-12-08 05:12:00 +00:00
2017-05-09 00:05:11 +00:00
#[ allow(non_snake_case) ]
2017-05-03 05:29:18 +00:00
#[ test ]
fn impl_mul ( ) {
2017-05-09 00:05:11 +00:00
let should_be_X_times_Y = & X * & Y ;
assert_eq! ( should_be_X_times_Y , X_TIMES_Y ) ;
2016-12-08 05:12:00 +00:00
}
2018-05-01 22:55:38 +00:00
#[ allow(non_snake_case) ]
#[ test ]
fn impl_product ( ) {
// Test that product works for non-empty iterators
let X_Y_vector = vec! [ X , Y ] ;
let should_be_X_times_Y : Scalar = X_Y_vector . iter ( ) . product ( ) ;
assert_eq! ( should_be_X_times_Y , X_TIMES_Y ) ;
// Test that product works for the empty iterator
let one = Scalar ::one ( ) ;
let empty_vector = vec! [ ] ;
let should_be_one : Scalar = empty_vector . iter ( ) . product ( ) ;
assert_eq! ( should_be_one , one ) ;
// Test that product works for iterators where Item = Scalar
let xs = [ Scalar ::from_u64 ( 2 ) ; 10 ] ;
let ys = [ Scalar ::from_u64 ( 3 ) ; 10 ] ;
// now zs is an iterator with Item = Scalar
let zs = xs . iter ( ) . zip ( ys . iter ( ) ) . map ( | ( x , y ) | x * y ) ;
let x_prod : Scalar = xs . iter ( ) . product ( ) ;
let y_prod : Scalar = ys . iter ( ) . product ( ) ;
let z_prod : Scalar = zs . product ( ) ;
assert_eq! ( x_prod , Scalar ::from_u64 ( 1024 ) ) ;
assert_eq! ( y_prod , Scalar ::from_u64 ( 59049 ) ) ;
assert_eq! ( z_prod , Scalar ::from_u64 ( 60466176 ) ) ;
assert_eq! ( x_prod * y_prod , z_prod ) ;
}
2018-05-01 22:56:23 +00:00
#[ test ]
fn impl_sum ( ) {
// Test that sum works for non-empty iterators
let two = Scalar ::from_u64 ( 2 ) ;
let one_vector = vec! [ Scalar ::one ( ) , Scalar ::one ( ) ] ;
let should_be_two : Scalar = one_vector . iter ( ) . sum ( ) ;
assert_eq! ( should_be_two , two ) ;
// Test that sum works for the empty iterator
let zero = Scalar ::zero ( ) ;
let empty_vector = vec! [ ] ;
let should_be_zero : Scalar = empty_vector . iter ( ) . sum ( ) ;
assert_eq! ( should_be_zero , zero ) ;
// Test that sum works for owned types
let xs = [ Scalar ::from_u64 ( 1 ) ; 10 ] ;
let ys = [ Scalar ::from_u64 ( 2 ) ; 10 ] ;
// now zs is an iterator with Item = Scalar
let zs = xs . iter ( ) . zip ( ys . iter ( ) ) . map ( | ( x , y ) | x + y ) ;
let x_sum : Scalar = xs . iter ( ) . sum ( ) ;
let y_sum : Scalar = ys . iter ( ) . sum ( ) ;
let z_sum : Scalar = zs . sum ( ) ;
assert_eq! ( x_sum , Scalar ::from_u64 ( 10 ) ) ;
assert_eq! ( y_sum , Scalar ::from_u64 ( 20 ) ) ;
assert_eq! ( z_sum , Scalar ::from_u64 ( 30 ) ) ;
assert_eq! ( x_sum + y_sum , z_sum ) ;
}
2017-08-22 04:35:26 +00:00
#[ test ]
fn square ( ) {
2017-12-01 00:44:51 +00:00
let expected = & X * & X ;
2017-08-22 04:35:26 +00:00
let actual = X . unpack ( ) . square ( ) . pack ( ) ;
for i in 0 .. 32 {
assert! ( expected [ i ] = = actual [ i ] ) ;
}
}
2016-12-08 05:12:00 +00:00
#[ test ]
2017-11-21 19:28:25 +00:00
fn reduce ( ) {
2017-11-23 00:04:47 +00:00
let biggest = Scalar ::from_bytes_mod_order ( [ 0xff ; 32 ] ) ;
2017-11-23 00:22:16 +00:00
assert_eq! ( biggest , CANONICAL_2_256_MINUS_1 ) ;
2017-11-21 19:28:25 +00:00
}
2016-12-08 05:12:00 +00:00
#[ test ]
2017-12-01 00:44:10 +00:00
fn from_bytes_mod_order_wide ( ) {
2017-03-17 21:42:40 +00:00
let mut bignum = [ 0 u8 ; 64 ] ;
2016-12-08 05:12:00 +00:00
// set bignum = x + 2^256x
for i in 0 .. 32 {
bignum [ i ] = X [ i ] ;
bignum [ 32 + i ] = X [ i ] ;
}
// 3958878930004874126169954872055634648693766179881526445624823978500314864344
// = x + 2^256x (mod l)
2017-11-23 00:04:47 +00:00
let reduced = Scalar {
bytes : [
216 , 154 , 179 , 139 , 210 , 121 , 2 , 71 ,
69 , 99 , 158 , 216 , 23 , 173 , 63 , 100 ,
204 , 0 , 91 , 50 , 219 , 153 , 57 , 249 ,
28 , 82 , 31 , 197 , 100 , 165 , 192 , 8 ,
] ,
} ;
2017-12-01 00:44:10 +00:00
let test_red = Scalar ::from_bytes_mod_order_wide ( & bignum ) ;
2016-12-08 05:12:00 +00:00
for i in 0 .. 32 {
assert! ( test_red [ i ] = = reduced [ i ] ) ;
}
}
2017-01-06 17:08:37 +00:00
2017-05-09 00:05:11 +00:00
#[ allow(non_snake_case) ]
2017-04-29 05:59:56 +00:00
#[ test ]
fn invert ( ) {
2017-05-03 05:29:18 +00:00
let inv_X = X . invert ( ) ;
2017-10-30 19:27:44 +00:00
assert_eq! ( inv_X , XINV ) ;
2017-05-03 05:29:18 +00:00
let should_be_one = & inv_X * & X ;
assert_eq! ( should_be_one , Scalar ::one ( ) ) ;
2017-04-29 05:59:56 +00:00
}
2017-01-06 17:08:37 +00:00
// Negating a scalar twice should result in the original scalar.
2017-05-09 00:05:11 +00:00
#[ allow(non_snake_case) ]
2017-01-06 17:08:37 +00:00
#[ test ]
2017-05-03 05:29:18 +00:00
fn neg_twice_is_identity ( ) {
let negative_X = - & X ;
let should_be_X = - & negative_X ;
2017-01-06 17:08:37 +00:00
2017-05-03 05:29:18 +00:00
assert_eq! ( should_be_X , X ) ;
2017-01-06 17:08:37 +00:00
}
2017-05-15 09:54:40 +00:00
2017-10-31 01:02:20 +00:00
#[ test ]
fn to_bytes_from_bytes_roundtrips ( ) {
let unpacked = X . unpack ( ) ;
let bytes = unpacked . to_bytes ( ) ;
let should_be_unpacked = UnpackedScalar ::from_bytes ( & bytes ) ;
assert_eq! ( should_be_unpacked . 0 , unpacked . 0 ) ;
}
2017-10-31 01:18:52 +00:00
#[ test ]
2017-12-01 00:44:10 +00:00
fn montgomery_reduce_matches_from_bytes_mod_order_wide ( ) {
2017-10-31 01:18:52 +00:00
let mut bignum = [ 0 u8 ; 64 ] ;
// set bignum = x + 2^256x
for i in 0 .. 32 {
bignum [ i ] = X [ i ] ;
bignum [ 32 + i ] = X [ i ] ;
}
// x + 2^256x (mod l)
// = 3958878930004874126169954872055634648693766179881526445624823978500314864344
2017-11-23 00:04:47 +00:00
let expected = Scalar {
bytes : [
216 , 154 , 179 , 139 , 210 , 121 , 2 , 71 ,
69 , 99 , 158 , 216 , 23 , 173 , 63 , 100 ,
204 , 0 , 91 , 50 , 219 , 153 , 57 , 249 ,
28 , 82 , 31 , 197 , 100 , 165 , 192 , 8
] ,
} ;
2017-12-01 00:44:10 +00:00
let reduced = Scalar ::from_bytes_mod_order_wide ( & bignum ) ;
2017-10-31 01:18:52 +00:00
// The reduced scalar should match the expected
2017-11-23 00:04:47 +00:00
assert_eq! ( reduced . bytes , expected . bytes ) ;
2017-10-31 01:18:52 +00:00
// (x + 2^256x) * R
let interim = UnpackedScalar ::mul_internal ( & UnpackedScalar ::from_bytes_wide ( & bignum ) ,
& constants ::R ) ;
// ((x + 2^256x) * R) / R (mod l)
let montgomery_reduced = UnpackedScalar ::montgomery_reduce ( & interim ) ;
// The Montgomery reduced scalar should match the reduced one, as well as the expected
assert_eq! ( montgomery_reduced . 0 , reduced . unpack ( ) . 0 ) ;
assert_eq! ( montgomery_reduced . 0 , expected . unpack ( ) . 0 )
}
2017-11-23 00:45:16 +00:00
#[ test ]
fn canonical_decoding ( ) {
// canonical encoding of 1667457891
let canonical_bytes = [ 99 , 99 , 99 , 99 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , ] ;
// encoding of
// 7265385991361016183439748078976496179028704920197054998554201349516117938192
// = 28380414028753969466561515933501938171588560817147392552250411230663687203 (mod l)
// non_canonical because unreduced mod l
let non_canonical_bytes_because_unreduced = [ 16 ; 32 ] ;
// encoding with high bit set, to check that the parser isn't pre-masking the high bit
let non_canonical_bytes_because_highbit = [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 128 ] ;
assert! ( Scalar ::from_canonical_bytes ( canonical_bytes ) . is_some ( ) ) ;
assert! ( Scalar ::from_canonical_bytes ( non_canonical_bytes_because_unreduced ) . is_none ( ) ) ;
assert! ( Scalar ::from_canonical_bytes ( non_canonical_bytes_because_highbit ) . is_none ( ) ) ;
}
2017-05-15 09:54:40 +00:00
#[ test ]
#[ cfg(feature = " serde " ) ]
fn serde_cbor_scalar_roundtrip ( ) {
2017-11-23 00:45:16 +00:00
// XXX remove serde_cbor
use serde_cbor ;
2017-05-15 09:54:40 +00:00
let output = serde_cbor ::to_vec ( & X ) . unwrap ( ) ;
let parsed : Scalar = serde_cbor ::from_slice ( & output ) . unwrap ( ) ;
assert_eq! ( parsed , X ) ;
}
2018-03-22 18:31:14 +00:00
2018-07-01 08:16:19 +00:00
#[ cfg(debug_assertions) ]
2018-03-22 18:31:14 +00:00
#[ test ]
#[ should_panic ]
fn batch_invert_with_a_zero_input_panics ( ) {
let mut xs = vec! [ Scalar ::one ( ) ; 16 ] ;
xs [ 3 ] = Scalar ::zero ( ) ;
// This should panic in debug mode.
Scalar ::batch_invert ( & mut xs ) ;
}
2018-06-30 15:49:54 +00:00
2018-06-30 22:29:02 +00:00
#[ test ]
fn batch_invert_empty ( ) {
assert_eq! ( Scalar ::one ( ) , Scalar ::batch_invert ( & mut [ ] ) ) ;
}
2018-06-30 15:49:54 +00:00
#[ test ]
fn batch_invert_consistency ( ) {
let mut x = Scalar ::from_u64 ( 1 ) ;
let mut v1 : Vec < _ > = ( 0 .. 16 ) . map ( | _ | { let tmp = x ; x = x + x ; tmp } ) . collect ( ) ;
let v2 = v1 . clone ( ) ;
let expected : Scalar = v1 . iter ( ) . product ( ) ;
let expected = expected . invert ( ) ;
let ret = Scalar ::batch_invert ( & mut v1 ) ;
assert_eq! ( ret , expected ) ;
for ( a , b ) in v1 . iter ( ) . zip ( v2 . iter ( ) ) {
assert_eq! ( a * b , Scalar ::one ( ) ) ;
}
}
2016-12-08 05:12:00 +00:00
}