RPM build fix (reverted CI changes which will need to be un-reverted or made conditional) and vendor Rust dependencies to make builds much faster in any CI system.
This commit is contained in:
679
zeroidc/vendor/ring/src/aead.rs
vendored
Normal file
679
zeroidc/vendor/ring/src/aead.rs
vendored
Normal file
@@ -0,0 +1,679 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Authenticated Encryption with Associated Data (AEAD).
|
||||
//!
|
||||
//! See [Authenticated encryption: relations among notions and analysis of the
|
||||
//! generic composition paradigm][AEAD] for an introduction to the concept of
|
||||
//! AEADs.
|
||||
//!
|
||||
//! [AEAD]: http://www-cse.ucsd.edu/~mihir/papers/oem.html
|
||||
//! [`crypto.cipher.AEAD`]: https://golang.org/pkg/crypto/cipher/#AEAD
|
||||
|
||||
use self::block::{Block, BLOCK_LEN};
|
||||
use crate::{constant_time, cpu, error, hkdf, polyfill};
|
||||
use core::ops::RangeFrom;
|
||||
|
||||
pub use self::{
|
||||
aes_gcm::{AES_128_GCM, AES_256_GCM},
|
||||
chacha20_poly1305::CHACHA20_POLY1305,
|
||||
nonce::{Nonce, NONCE_LEN},
|
||||
};
|
||||
|
||||
/// A sequences of unique nonces.
|
||||
///
|
||||
/// A given `NonceSequence` must never return the same `Nonce` twice from
|
||||
/// `advance()`.
|
||||
///
|
||||
/// A simple counter is a reasonable (but probably not ideal) `NonceSequence`.
|
||||
///
|
||||
/// Intentionally not `Clone` or `Copy` since cloning would allow duplication
|
||||
/// of the sequence.
|
||||
pub trait NonceSequence {
|
||||
/// Returns the next nonce in the sequence.
|
||||
///
|
||||
/// This may fail if "too many" nonces have been requested, where how many
|
||||
/// is too many is up to the implementation of `NonceSequence`. An
|
||||
/// implementation may that enforce a maximum number of records are
|
||||
/// sent/received under a key this way. Once `advance()` fails, it must
|
||||
/// fail for all subsequent calls.
|
||||
fn advance(&mut self) -> Result<Nonce, error::Unspecified>;
|
||||
}
|
||||
|
||||
/// An AEAD key bound to a nonce sequence.
|
||||
pub trait BoundKey<N: NonceSequence>: core::fmt::Debug {
|
||||
/// Constructs a new key from the given `UnboundKey` and `NonceSequence`.
|
||||
fn new(key: UnboundKey, nonce_sequence: N) -> Self;
|
||||
|
||||
/// The key's AEAD algorithm.
|
||||
fn algorithm(&self) -> &'static Algorithm;
|
||||
}
|
||||
|
||||
/// An AEAD key for authenticating and decrypting ("opening"), bound to a nonce
|
||||
/// sequence.
|
||||
///
|
||||
/// Intentionally not `Clone` or `Copy` since cloning would allow duplication
|
||||
/// of the nonce sequence.
|
||||
pub struct OpeningKey<N: NonceSequence> {
|
||||
key: UnboundKey,
|
||||
nonce_sequence: N,
|
||||
}
|
||||
|
||||
impl<N: NonceSequence> BoundKey<N> for OpeningKey<N> {
|
||||
fn new(key: UnboundKey, nonce_sequence: N) -> Self {
|
||||
Self {
|
||||
key,
|
||||
nonce_sequence,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn algorithm(&self) -> &'static Algorithm {
|
||||
self.key.algorithm
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NonceSequence> core::fmt::Debug for OpeningKey<N> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
f.debug_struct("OpeningKey")
|
||||
.field("algorithm", &self.algorithm())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NonceSequence> OpeningKey<N> {
|
||||
/// Authenticates and decrypts (“opens”) data in place.
|
||||
///
|
||||
/// `aad` is the additional authenticated data (AAD), if any.
|
||||
///
|
||||
/// On input, `in_out` must be the ciphertext followed by the tag. When
|
||||
/// `open_in_place()` returns `Ok(plaintext)`, the input ciphertext
|
||||
/// has been overwritten by the plaintext; `plaintext` will refer to the
|
||||
/// plaintext without the tag.
|
||||
///
|
||||
/// When `open_in_place()` returns `Err(..)`, `in_out` may have been
|
||||
/// overwritten in an unspecified way.
|
||||
#[inline]
|
||||
pub fn open_in_place<'in_out, A>(
|
||||
&mut self,
|
||||
aad: Aad<A>,
|
||||
in_out: &'in_out mut [u8],
|
||||
) -> Result<&'in_out mut [u8], error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
{
|
||||
self.open_within(aad, in_out, 0..)
|
||||
}
|
||||
|
||||
/// Authenticates and decrypts (“opens”) data in place, with a shift.
|
||||
///
|
||||
/// `aad` is the additional authenticated data (AAD), if any.
|
||||
///
|
||||
/// On input, `in_out[ciphertext_and_tag]` must be the ciphertext followed
|
||||
/// by the tag. When `open_within()` returns `Ok(plaintext)`, the plaintext
|
||||
/// will be at `in_out[0..plaintext.len()]`. In other words, the following
|
||||
/// two code fragments are equivalent for valid values of
|
||||
/// `ciphertext_and_tag`, except `open_within` will often be more efficient:
|
||||
///
|
||||
///
|
||||
/// ```skip
|
||||
/// let plaintext = key.open_within(aad, in_out, cipertext_and_tag)?;
|
||||
/// ```
|
||||
///
|
||||
/// ```skip
|
||||
/// let ciphertext_and_tag_len = in_out[ciphertext_and_tag].len();
|
||||
/// in_out.copy_within(ciphertext_and_tag, 0);
|
||||
/// let plaintext = key.open_in_place(aad, &mut in_out[..ciphertext_and_tag_len])?;
|
||||
/// ```
|
||||
///
|
||||
/// Similarly, `key.open_within(aad, in_out, 0..)` is equivalent to
|
||||
/// `key.open_in_place(aad, in_out)`.
|
||||
///
|
||||
/// When `open_in_place()` returns `Err(..)`, `in_out` may have been
|
||||
/// overwritten in an unspecified way.
|
||||
///
|
||||
/// The shifting feature is useful in the case where multiple packets are
|
||||
/// being reassembled in place. Consider this example where the peer has
|
||||
/// sent the message “Split stream reassembled in place” split into
|
||||
/// three sealed packets:
|
||||
///
|
||||
/// ```ascii-art
|
||||
/// Packet 1 Packet 2 Packet 3
|
||||
/// Input: [Header][Ciphertext][Tag][Header][Ciphertext][Tag][Header][Ciphertext][Tag]
|
||||
/// | +--------------+ |
|
||||
/// +------+ +-----+ +----------------------------------+
|
||||
/// v v v
|
||||
/// Output: [Plaintext][Plaintext][Plaintext]
|
||||
/// “Split stream reassembled in place”
|
||||
/// ```
|
||||
///
|
||||
/// This reassembly be accomplished with three calls to `open_within()`.
|
||||
#[inline]
|
||||
pub fn open_within<'in_out, A>(
|
||||
&mut self,
|
||||
aad: Aad<A>,
|
||||
in_out: &'in_out mut [u8],
|
||||
ciphertext_and_tag: RangeFrom<usize>,
|
||||
) -> Result<&'in_out mut [u8], error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
{
|
||||
open_within_(
|
||||
&self.key,
|
||||
self.nonce_sequence.advance()?,
|
||||
aad,
|
||||
in_out,
|
||||
ciphertext_and_tag,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn open_within_<'in_out, A: AsRef<[u8]>>(
|
||||
key: &UnboundKey,
|
||||
nonce: Nonce,
|
||||
Aad(aad): Aad<A>,
|
||||
in_out: &'in_out mut [u8],
|
||||
ciphertext_and_tag: RangeFrom<usize>,
|
||||
) -> Result<&'in_out mut [u8], error::Unspecified> {
|
||||
fn open_within<'in_out>(
|
||||
key: &UnboundKey,
|
||||
nonce: Nonce,
|
||||
aad: Aad<&[u8]>,
|
||||
in_out: &'in_out mut [u8],
|
||||
ciphertext_and_tag: RangeFrom<usize>,
|
||||
) -> Result<&'in_out mut [u8], error::Unspecified> {
|
||||
let in_prefix_len = ciphertext_and_tag.start;
|
||||
let ciphertext_and_tag_len = in_out
|
||||
.len()
|
||||
.checked_sub(in_prefix_len)
|
||||
.ok_or(error::Unspecified)?;
|
||||
let ciphertext_len = ciphertext_and_tag_len
|
||||
.checked_sub(TAG_LEN)
|
||||
.ok_or(error::Unspecified)?;
|
||||
check_per_nonce_max_bytes(key.algorithm, ciphertext_len)?;
|
||||
let (in_out, received_tag) = in_out.split_at_mut(in_prefix_len + ciphertext_len);
|
||||
let Tag(calculated_tag) = (key.algorithm.open)(
|
||||
&key.inner,
|
||||
nonce,
|
||||
aad,
|
||||
in_prefix_len,
|
||||
in_out,
|
||||
key.cpu_features,
|
||||
);
|
||||
if constant_time::verify_slices_are_equal(calculated_tag.as_ref(), received_tag).is_err() {
|
||||
// Zero out the plaintext so that it isn't accidentally leaked or used
|
||||
// after verification fails. It would be safest if we could check the
|
||||
// tag before decrypting, but some `open` implementations interleave
|
||||
// authentication with decryption for performance.
|
||||
for b in &mut in_out[..ciphertext_len] {
|
||||
*b = 0;
|
||||
}
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
// `ciphertext_len` is also the plaintext length.
|
||||
Ok(&mut in_out[..ciphertext_len])
|
||||
}
|
||||
|
||||
open_within(
|
||||
key,
|
||||
nonce,
|
||||
Aad::from(aad.as_ref()),
|
||||
in_out,
|
||||
ciphertext_and_tag,
|
||||
)
|
||||
}
|
||||
|
||||
/// An AEAD key for encrypting and signing ("sealing"), bound to a nonce
|
||||
/// sequence.
|
||||
///
|
||||
/// Intentionally not `Clone` or `Copy` since cloning would allow duplication
|
||||
/// of the nonce sequence.
|
||||
pub struct SealingKey<N: NonceSequence> {
|
||||
key: UnboundKey,
|
||||
nonce_sequence: N,
|
||||
}
|
||||
|
||||
impl<N: NonceSequence> BoundKey<N> for SealingKey<N> {
|
||||
fn new(key: UnboundKey, nonce_sequence: N) -> Self {
|
||||
Self {
|
||||
key,
|
||||
nonce_sequence,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn algorithm(&self) -> &'static Algorithm {
|
||||
self.key.algorithm
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NonceSequence> core::fmt::Debug for SealingKey<N> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
f.debug_struct("SealingKey")
|
||||
.field("algorithm", &self.algorithm())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NonceSequence> SealingKey<N> {
|
||||
/// Deprecated. Renamed to `seal_in_place_append_tag()`.
|
||||
#[deprecated(note = "Renamed to `seal_in_place_append_tag`.")]
|
||||
#[inline]
|
||||
pub fn seal_in_place<A, InOut>(
|
||||
&mut self,
|
||||
aad: Aad<A>,
|
||||
in_out: &mut InOut,
|
||||
) -> Result<(), error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
InOut: AsMut<[u8]> + for<'in_out> Extend<&'in_out u8>,
|
||||
{
|
||||
self.seal_in_place_append_tag(aad, in_out)
|
||||
}
|
||||
|
||||
/// Encrypts and signs (“seals”) data in place, appending the tag to the
|
||||
/// resulting ciphertext.
|
||||
///
|
||||
/// `key.seal_in_place_append_tag(aad, in_out)` is equivalent to:
|
||||
///
|
||||
/// ```skip
|
||||
/// key.seal_in_place_separate_tag(aad, in_out.as_mut())
|
||||
/// .map(|tag| in_out.extend(tag.as_ref()))
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn seal_in_place_append_tag<A, InOut>(
|
||||
&mut self,
|
||||
aad: Aad<A>,
|
||||
in_out: &mut InOut,
|
||||
) -> Result<(), error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
InOut: AsMut<[u8]> + for<'in_out> Extend<&'in_out u8>,
|
||||
{
|
||||
self.seal_in_place_separate_tag(aad, in_out.as_mut())
|
||||
.map(|tag| in_out.extend(tag.as_ref()))
|
||||
}
|
||||
|
||||
/// Encrypts and signs (“seals”) data in place.
|
||||
///
|
||||
/// `aad` is the additional authenticated data (AAD), if any. This is
|
||||
/// authenticated but not encrypted. The type `A` could be a byte slice
|
||||
/// `&[u8]`, a byte array `[u8; N]` for some constant `N`, `Vec<u8>`, etc.
|
||||
/// If there is no AAD then use `Aad::empty()`.
|
||||
///
|
||||
/// The plaintext is given as the input value of `in_out`. `seal_in_place()`
|
||||
/// will overwrite the plaintext with the ciphertext and return the tag.
|
||||
/// For most protocols, the caller must append the tag to the ciphertext.
|
||||
/// The tag will be `self.algorithm.tag_len()` bytes long.
|
||||
#[inline]
|
||||
pub fn seal_in_place_separate_tag<A>(
|
||||
&mut self,
|
||||
aad: Aad<A>,
|
||||
in_out: &mut [u8],
|
||||
) -> Result<Tag, error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
{
|
||||
seal_in_place_separate_tag_(
|
||||
&self.key,
|
||||
self.nonce_sequence.advance()?,
|
||||
Aad::from(aad.as_ref()),
|
||||
in_out,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn seal_in_place_separate_tag_(
|
||||
key: &UnboundKey,
|
||||
nonce: Nonce,
|
||||
aad: Aad<&[u8]>,
|
||||
in_out: &mut [u8],
|
||||
) -> Result<Tag, error::Unspecified> {
|
||||
check_per_nonce_max_bytes(key.algorithm, in_out.len())?;
|
||||
Ok((key.algorithm.seal)(
|
||||
&key.inner,
|
||||
nonce,
|
||||
aad,
|
||||
in_out,
|
||||
key.cpu_features,
|
||||
))
|
||||
}
|
||||
|
||||
/// The additionally authenticated data (AAD) for an opening or sealing
|
||||
/// operation. This data is authenticated but is **not** encrypted.
|
||||
///
|
||||
/// The type `A` could be a byte slice `&[u8]`, a byte array `[u8; N]`
|
||||
/// for some constant `N`, `Vec<u8>`, etc.
|
||||
pub struct Aad<A: AsRef<[u8]>>(A);
|
||||
|
||||
impl<A: AsRef<[u8]>> Aad<A> {
|
||||
/// Construct the `Aad` from the given bytes.
|
||||
#[inline]
|
||||
pub fn from(aad: A) -> Self {
|
||||
Aad(aad)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> AsRef<[u8]> for Aad<A>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
{
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl Aad<[u8; 0]> {
|
||||
/// Construct an empty `Aad`.
|
||||
pub fn empty() -> Self {
|
||||
Self::from([])
|
||||
}
|
||||
}
|
||||
|
||||
/// An AEAD key without a designated role or nonce sequence.
|
||||
pub struct UnboundKey {
|
||||
inner: KeyInner,
|
||||
algorithm: &'static Algorithm,
|
||||
cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for UnboundKey {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
f.debug_struct("UnboundKey")
|
||||
.field("algorithm", &self.algorithm)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant, variant_size_differences)]
|
||||
enum KeyInner {
|
||||
AesGcm(aes_gcm::Key),
|
||||
ChaCha20Poly1305(chacha20_poly1305::Key),
|
||||
}
|
||||
|
||||
impl UnboundKey {
|
||||
/// Constructs an `UnboundKey`.
|
||||
///
|
||||
/// Fails if `key_bytes.len() != algorithm.key_len()`.
|
||||
pub fn new(
|
||||
algorithm: &'static Algorithm,
|
||||
key_bytes: &[u8],
|
||||
) -> Result<Self, error::Unspecified> {
|
||||
let cpu_features = cpu::features();
|
||||
Ok(Self {
|
||||
inner: (algorithm.init)(key_bytes, cpu_features)?,
|
||||
algorithm,
|
||||
cpu_features,
|
||||
})
|
||||
}
|
||||
|
||||
/// The key's AEAD algorithm.
|
||||
#[inline]
|
||||
pub fn algorithm(&self) -> &'static Algorithm {
|
||||
self.algorithm
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hkdf::Okm<'_, &'static Algorithm>> for UnboundKey {
|
||||
fn from(okm: hkdf::Okm<&'static Algorithm>) -> Self {
|
||||
let mut key_bytes = [0; MAX_KEY_LEN];
|
||||
let key_bytes = &mut key_bytes[..okm.len().key_len];
|
||||
let algorithm = *okm.len();
|
||||
okm.fill(key_bytes).unwrap();
|
||||
Self::new(algorithm, key_bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl hkdf::KeyType for &'static Algorithm {
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
self.key_len()
|
||||
}
|
||||
}
|
||||
|
||||
/// Immutable keys for use in situations where `OpeningKey`/`SealingKey` and
|
||||
/// `NonceSequence` cannot reasonably be used.
|
||||
///
|
||||
/// Prefer to use `OpeningKey`/`SealingKey` and `NonceSequence` when practical.
|
||||
pub struct LessSafeKey {
|
||||
key: UnboundKey,
|
||||
}
|
||||
|
||||
impl LessSafeKey {
|
||||
/// Constructs a `LessSafeKey` from an `UnboundKey`.
|
||||
pub fn new(key: UnboundKey) -> Self {
|
||||
Self { key }
|
||||
}
|
||||
|
||||
/// Like [`OpeningKey::open_in_place()`], except it accepts an arbitrary nonce.
|
||||
///
|
||||
/// `nonce` must be unique for every use of the key to open data.
|
||||
#[inline]
|
||||
pub fn open_in_place<'in_out, A>(
|
||||
&self,
|
||||
nonce: Nonce,
|
||||
aad: Aad<A>,
|
||||
in_out: &'in_out mut [u8],
|
||||
) -> Result<&'in_out mut [u8], error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
{
|
||||
self.open_within(nonce, aad, in_out, 0..)
|
||||
}
|
||||
|
||||
/// Like [`OpeningKey::open_within()`], except it accepts an arbitrary nonce.
|
||||
///
|
||||
/// `nonce` must be unique for every use of the key to open data.
|
||||
#[inline]
|
||||
pub fn open_within<'in_out, A>(
|
||||
&self,
|
||||
nonce: Nonce,
|
||||
aad: Aad<A>,
|
||||
in_out: &'in_out mut [u8],
|
||||
ciphertext_and_tag: RangeFrom<usize>,
|
||||
) -> Result<&'in_out mut [u8], error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
{
|
||||
open_within_(&self.key, nonce, aad, in_out, ciphertext_and_tag)
|
||||
}
|
||||
|
||||
/// Deprecated. Renamed to `seal_in_place_append_tag()`.
|
||||
#[deprecated(note = "Renamed to `seal_in_place_append_tag`.")]
|
||||
#[inline]
|
||||
pub fn seal_in_place<A, InOut>(
|
||||
&self,
|
||||
nonce: Nonce,
|
||||
aad: Aad<A>,
|
||||
in_out: &mut InOut,
|
||||
) -> Result<(), error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
InOut: AsMut<[u8]> + for<'in_out> Extend<&'in_out u8>,
|
||||
{
|
||||
self.seal_in_place_append_tag(nonce, aad, in_out)
|
||||
}
|
||||
|
||||
/// Like [`SealingKey::seal_in_place_append_tag()`], except it accepts an
|
||||
/// arbitrary nonce.
|
||||
///
|
||||
/// `nonce` must be unique for every use of the key to seal data.
|
||||
#[inline]
|
||||
pub fn seal_in_place_append_tag<A, InOut>(
|
||||
&self,
|
||||
nonce: Nonce,
|
||||
aad: Aad<A>,
|
||||
in_out: &mut InOut,
|
||||
) -> Result<(), error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
InOut: AsMut<[u8]> + for<'in_out> Extend<&'in_out u8>,
|
||||
{
|
||||
self.seal_in_place_separate_tag(nonce, aad, in_out.as_mut())
|
||||
.map(|tag| in_out.extend(tag.as_ref()))
|
||||
}
|
||||
|
||||
/// Like `SealingKey::seal_in_place_separate_tag()`, except it accepts an
|
||||
/// arbitrary nonce.
|
||||
///
|
||||
/// `nonce` must be unique for every use of the key to seal data.
|
||||
#[inline]
|
||||
pub fn seal_in_place_separate_tag<A>(
|
||||
&self,
|
||||
nonce: Nonce,
|
||||
aad: Aad<A>,
|
||||
in_out: &mut [u8],
|
||||
) -> Result<Tag, error::Unspecified>
|
||||
where
|
||||
A: AsRef<[u8]>,
|
||||
{
|
||||
seal_in_place_separate_tag_(&self.key, nonce, Aad::from(aad.as_ref()), in_out)
|
||||
}
|
||||
|
||||
/// The key's AEAD algorithm.
|
||||
#[inline]
|
||||
pub fn algorithm(&self) -> &'static Algorithm {
|
||||
&self.key.algorithm
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for LessSafeKey {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
f.debug_struct("LessSafeKey")
|
||||
.field("algorithm", self.algorithm())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// An AEAD Algorithm.
|
||||
pub struct Algorithm {
|
||||
init: fn(key: &[u8], cpu_features: cpu::Features) -> Result<KeyInner, error::Unspecified>,
|
||||
|
||||
seal: fn(
|
||||
key: &KeyInner,
|
||||
nonce: Nonce,
|
||||
aad: Aad<&[u8]>,
|
||||
in_out: &mut [u8],
|
||||
cpu_features: cpu::Features,
|
||||
) -> Tag,
|
||||
open: fn(
|
||||
key: &KeyInner,
|
||||
nonce: Nonce,
|
||||
aad: Aad<&[u8]>,
|
||||
in_prefix_len: usize,
|
||||
in_out: &mut [u8],
|
||||
cpu_features: cpu::Features,
|
||||
) -> Tag,
|
||||
|
||||
key_len: usize,
|
||||
id: AlgorithmID,
|
||||
|
||||
/// Use `max_input_len!()` to initialize this.
|
||||
// TODO: Make this `usize`.
|
||||
max_input_len: u64,
|
||||
}
|
||||
|
||||
const fn max_input_len(block_len: usize, overhead_blocks_per_nonce: usize) -> u64 {
|
||||
// Each of our AEADs use a 32-bit block counter so the maximum is the
|
||||
// largest input that will not overflow the counter.
|
||||
((1u64 << 32) - polyfill::u64_from_usize(overhead_blocks_per_nonce))
|
||||
* polyfill::u64_from_usize(block_len)
|
||||
}
|
||||
|
||||
impl Algorithm {
|
||||
/// The length of the key.
|
||||
#[inline(always)]
|
||||
pub fn key_len(&self) -> usize {
|
||||
self.key_len
|
||||
}
|
||||
|
||||
/// The length of a tag.
|
||||
///
|
||||
/// See also `MAX_TAG_LEN`.
|
||||
#[inline(always)]
|
||||
pub fn tag_len(&self) -> usize {
|
||||
TAG_LEN
|
||||
}
|
||||
|
||||
/// The length of the nonces.
|
||||
#[inline(always)]
|
||||
pub fn nonce_len(&self) -> usize {
|
||||
NONCE_LEN
|
||||
}
|
||||
}
|
||||
|
||||
derive_debug_via_id!(Algorithm);
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum AlgorithmID {
|
||||
AES_128_GCM,
|
||||
AES_256_GCM,
|
||||
CHACHA20_POLY1305,
|
||||
}
|
||||
|
||||
impl PartialEq for Algorithm {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Algorithm {}
|
||||
|
||||
/// An authentication tag.
|
||||
#[must_use]
|
||||
#[repr(C)]
|
||||
pub struct Tag([u8; TAG_LEN]);
|
||||
|
||||
impl AsRef<[u8]> for Tag {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_KEY_LEN: usize = 32;
|
||||
|
||||
// All the AEADs we support use 128-bit tags.
|
||||
const TAG_LEN: usize = BLOCK_LEN;
|
||||
|
||||
/// The maximum length of a tag for the algorithms in this module.
|
||||
pub const MAX_TAG_LEN: usize = TAG_LEN;
|
||||
|
||||
fn check_per_nonce_max_bytes(alg: &Algorithm, in_out_len: usize) -> Result<(), error::Unspecified> {
|
||||
if polyfill::u64_from_usize(in_out_len) > alg.max_input_len {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Direction {
|
||||
Opening { in_prefix_len: usize },
|
||||
Sealing,
|
||||
}
|
||||
|
||||
mod aes;
|
||||
mod aes_gcm;
|
||||
mod block;
|
||||
mod chacha;
|
||||
mod chacha20_poly1305;
|
||||
pub mod chacha20_poly1305_openssh;
|
||||
mod counter;
|
||||
mod gcm;
|
||||
mod iv;
|
||||
mod nonce;
|
||||
mod poly1305;
|
||||
pub mod quic;
|
||||
mod shift;
|
||||
443
zeroidc/vendor/ring/src/aead/aes.rs
vendored
Normal file
443
zeroidc/vendor/ring/src/aead/aes.rs
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::{counter, iv::Iv, quic::Sample, Block, Direction, BLOCK_LEN};
|
||||
use crate::{bits::BitLength, c, cpu, endian::*, error, polyfill};
|
||||
|
||||
pub(crate) struct Key {
|
||||
inner: AES_KEY,
|
||||
cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
macro_rules! set_encrypt_key {
|
||||
( $name:ident, $bytes:expr, $key_bits:expr, $key:expr ) => {{
|
||||
extern "C" {
|
||||
fn $name(user_key: *const u8, bits: c::uint, key: &mut AES_KEY) -> c::int;
|
||||
}
|
||||
set_encrypt_key($name, $bytes, $key_bits, $key)
|
||||
}};
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_encrypt_key(
|
||||
f: unsafe extern "C" fn(*const u8, c::uint, &mut AES_KEY) -> c::int,
|
||||
bytes: &[u8],
|
||||
key_bits: BitLength,
|
||||
key: &mut AES_KEY,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
// Unusually, in this case zero means success and non-zero means failure.
|
||||
if 0 == unsafe { f(bytes.as_ptr(), key_bits.as_usize_bits() as c::uint, key) } {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(error::Unspecified)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! encrypt_block {
|
||||
($name:ident, $block:expr, $key:expr) => {{
|
||||
extern "C" {
|
||||
fn $name(a: &Block, r: *mut Block, key: &AES_KEY);
|
||||
}
|
||||
encrypt_block_($name, $block, $key)
|
||||
}};
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn encrypt_block_(
|
||||
f: unsafe extern "C" fn(&Block, *mut Block, &AES_KEY),
|
||||
a: Block,
|
||||
key: &Key,
|
||||
) -> Block {
|
||||
let mut result = core::mem::MaybeUninit::uninit();
|
||||
unsafe {
|
||||
f(&a, result.as_mut_ptr(), &key.inner);
|
||||
result.assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! ctr32_encrypt_blocks {
|
||||
($name:ident, $in_out:expr, $in_prefix_len:expr, $key:expr, $ivec:expr ) => {{
|
||||
extern "C" {
|
||||
fn $name(
|
||||
input: *const u8,
|
||||
output: *mut u8,
|
||||
blocks: c::size_t,
|
||||
key: &AES_KEY,
|
||||
ivec: &Counter,
|
||||
);
|
||||
}
|
||||
ctr32_encrypt_blocks_($name, $in_out, $in_prefix_len, $key, $ivec)
|
||||
}};
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ctr32_encrypt_blocks_(
|
||||
f: unsafe extern "C" fn(
|
||||
input: *const u8,
|
||||
output: *mut u8,
|
||||
blocks: c::size_t,
|
||||
key: &AES_KEY,
|
||||
ivec: &Counter,
|
||||
),
|
||||
in_out: &mut [u8],
|
||||
in_prefix_len: usize,
|
||||
key: &AES_KEY,
|
||||
ctr: &mut Counter,
|
||||
) {
|
||||
let in_out_len = in_out.len().checked_sub(in_prefix_len).unwrap();
|
||||
assert_eq!(in_out_len % BLOCK_LEN, 0);
|
||||
|
||||
let blocks = in_out_len / BLOCK_LEN;
|
||||
let blocks_u32 = blocks as u32;
|
||||
assert_eq!(blocks, polyfill::usize_from_u32(blocks_u32));
|
||||
|
||||
let input = in_out[in_prefix_len..].as_ptr();
|
||||
let output = in_out.as_mut_ptr();
|
||||
|
||||
unsafe {
|
||||
f(input, output, blocks, &key, ctr);
|
||||
}
|
||||
ctr.increment_by_less_safe(blocks_u32);
|
||||
}
|
||||
|
||||
impl Key {
|
||||
#[inline]
|
||||
pub fn new(
|
||||
bytes: &[u8],
|
||||
variant: Variant,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Result<Self, error::Unspecified> {
|
||||
let key_bits = match variant {
|
||||
Variant::AES_128 => BitLength::from_usize_bits(128),
|
||||
Variant::AES_256 => BitLength::from_usize_bits(256),
|
||||
};
|
||||
if BitLength::from_usize_bytes(bytes.len())? != key_bits {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
let mut key = AES_KEY {
|
||||
rd_key: [0u32; 4 * (MAX_ROUNDS + 1)],
|
||||
rounds: 0,
|
||||
};
|
||||
|
||||
match detect_implementation(cpu_features) {
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
Implementation::HWAES => {
|
||||
set_encrypt_key!(GFp_aes_hw_set_encrypt_key, bytes, key_bits, &mut key)?
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
Implementation::VPAES_BSAES => {
|
||||
set_encrypt_key!(GFp_vpaes_set_encrypt_key, bytes, key_bits, &mut key)?
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
Implementation::NOHW => {
|
||||
set_encrypt_key!(GFp_aes_nohw_set_encrypt_key, bytes, key_bits, &mut key)?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
inner: key,
|
||||
cpu_features,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn encrypt_block(&self, a: Block) -> Block {
|
||||
match detect_implementation(self.cpu_features) {
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
Implementation::HWAES => encrypt_block!(GFp_aes_hw_encrypt, a, self),
|
||||
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
Implementation::VPAES_BSAES => encrypt_block!(GFp_vpaes_encrypt, a, self),
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
Implementation::NOHW => encrypt_block!(GFp_aes_nohw_encrypt, a, self),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn encrypt_iv_xor_block(&self, iv: Iv, input: Block) -> Block {
|
||||
let mut output = self.encrypt_block(Block::from(&iv.into_bytes_less_safe()));
|
||||
output.bitxor_assign(input);
|
||||
output
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn ctr32_encrypt_blocks(
|
||||
&self,
|
||||
in_out: &mut [u8],
|
||||
direction: Direction,
|
||||
ctr: &mut Counter,
|
||||
) {
|
||||
let in_prefix_len = match direction {
|
||||
Direction::Opening { in_prefix_len } => in_prefix_len,
|
||||
Direction::Sealing => 0,
|
||||
};
|
||||
|
||||
let in_out_len = in_out.len().checked_sub(in_prefix_len).unwrap();
|
||||
|
||||
assert_eq!(in_out_len % BLOCK_LEN, 0);
|
||||
|
||||
match detect_implementation(self.cpu_features) {
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
Implementation::HWAES => ctr32_encrypt_blocks!(
|
||||
GFp_aes_hw_ctr32_encrypt_blocks,
|
||||
in_out,
|
||||
in_prefix_len,
|
||||
&self.inner,
|
||||
ctr
|
||||
),
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64"))]
|
||||
Implementation::VPAES_BSAES => {
|
||||
// 8 blocks is the cut-off point where it's faster to use BSAES.
|
||||
#[cfg(target_arch = "arm")]
|
||||
let in_out = if in_out_len >= 8 * BLOCK_LEN {
|
||||
let remainder = in_out_len % (8 * BLOCK_LEN);
|
||||
let bsaes_in_out_len = if remainder < (4 * BLOCK_LEN) {
|
||||
in_out_len - remainder
|
||||
} else {
|
||||
in_out_len
|
||||
};
|
||||
|
||||
let mut bsaes_key = AES_KEY {
|
||||
rd_key: [0u32; 4 * (MAX_ROUNDS + 1)],
|
||||
rounds: 0,
|
||||
};
|
||||
extern "C" {
|
||||
fn GFp_vpaes_encrypt_key_to_bsaes(
|
||||
bsaes_key: &mut AES_KEY,
|
||||
vpaes_key: &AES_KEY,
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
GFp_vpaes_encrypt_key_to_bsaes(&mut bsaes_key, &self.inner);
|
||||
}
|
||||
ctr32_encrypt_blocks!(
|
||||
GFp_bsaes_ctr32_encrypt_blocks,
|
||||
&mut in_out[..(bsaes_in_out_len + in_prefix_len)],
|
||||
in_prefix_len,
|
||||
&bsaes_key,
|
||||
ctr
|
||||
);
|
||||
|
||||
&mut in_out[bsaes_in_out_len..]
|
||||
} else {
|
||||
in_out
|
||||
};
|
||||
|
||||
ctr32_encrypt_blocks!(
|
||||
GFp_vpaes_ctr32_encrypt_blocks,
|
||||
in_out,
|
||||
in_prefix_len,
|
||||
&self.inner,
|
||||
ctr
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86"))]
|
||||
Implementation::VPAES_BSAES => {
|
||||
super::shift::shift_full_blocks(in_out, in_prefix_len, |input| {
|
||||
self.encrypt_iv_xor_block(ctr.increment(), Block::from(input))
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
Implementation::NOHW => ctr32_encrypt_blocks!(
|
||||
GFp_aes_nohw_ctr32_encrypt_blocks,
|
||||
in_out,
|
||||
in_prefix_len,
|
||||
&self.inner,
|
||||
ctr
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_mask(&self, sample: Sample) -> [u8; 5] {
|
||||
let block = self.encrypt_block(Block::from(&sample));
|
||||
|
||||
let mut out: [u8; 5] = [0; 5];
|
||||
out.copy_from_slice(&block.as_ref()[..5]);
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
// TODO: use `matches!` when MSRV increases to 1.42.0 and remove this
|
||||
// `#[allow(...)]`
|
||||
#[allow(clippy::unknown_clippy_lints)]
|
||||
#[allow(clippy::match_like_matches_macro)]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[must_use]
|
||||
pub fn is_aes_hw(&self) -> bool {
|
||||
match detect_implementation(self.cpu_features) {
|
||||
Implementation::HWAES => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[must_use]
|
||||
pub(super) fn inner_less_safe(&self) -> &AES_KEY {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
// Keep this in sync with AES_KEY in aes.h.
|
||||
#[repr(C)]
|
||||
pub(super) struct AES_KEY {
|
||||
pub rd_key: [u32; 4 * (MAX_ROUNDS + 1)],
|
||||
pub rounds: c::uint,
|
||||
}
|
||||
|
||||
// Keep this in sync with `AES_MAXNR` in aes.h.
|
||||
const MAX_ROUNDS: usize = 14;
|
||||
|
||||
pub enum Variant {
|
||||
AES_128,
|
||||
AES_256,
|
||||
}
|
||||
|
||||
pub type Counter = counter::Counter<BigEndian<u32>>;
|
||||
|
||||
#[repr(C)] // Only so `Key` can be `#[repr(C)]`
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Implementation {
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
HWAES = 1,
|
||||
|
||||
// On "arm" only, this indicates that the bsaes implementation may be used.
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
VPAES_BSAES = 2,
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
NOHW = 3,
|
||||
}
|
||||
|
||||
fn detect_implementation(cpu_features: cpu::Features) -> Implementation {
|
||||
// `cpu_features` is only used for specific platforms.
|
||||
#[cfg(not(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
)))]
|
||||
let _cpu_features = cpu_features;
|
||||
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
{
|
||||
if cpu::intel::AES.available(cpu_features) || cpu::arm::AES.available(cpu_features) {
|
||||
return Implementation::HWAES;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
|
||||
{
|
||||
if cpu::intel::SSSE3.available(cpu_features) {
|
||||
return Implementation::VPAES_BSAES;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
{
|
||||
if cpu::arm::NEON.available(cpu_features) {
|
||||
return Implementation::VPAES_BSAES;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
Implementation::VPAES_BSAES
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
{
|
||||
Implementation::NOHW
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{super::BLOCK_LEN, *};
|
||||
use crate::test;
|
||||
use core::convert::TryInto;
|
||||
|
||||
#[test]
|
||||
pub fn test_aes() {
|
||||
test::run(test_file!("aes_tests.txt"), |section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
let key = consume_key(test_case, "Key");
|
||||
let input = test_case.consume_bytes("Input");
|
||||
let input: &[u8; BLOCK_LEN] = input.as_slice().try_into()?;
|
||||
let expected_output = test_case.consume_bytes("Output");
|
||||
|
||||
let block = Block::from(input);
|
||||
let output = key.encrypt_block(block);
|
||||
assert_eq!(output.as_ref(), &expected_output[..]);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn consume_key(test_case: &mut test::TestCase, name: &str) -> Key {
|
||||
let key = test_case.consume_bytes(name);
|
||||
let variant = match key.len() {
|
||||
16 => Variant::AES_128,
|
||||
32 => Variant::AES_256,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
Key::new(&key[..], variant, cpu::features()).unwrap()
|
||||
}
|
||||
}
|
||||
301
zeroidc/vendor/ring/src/aead/aes_gcm.rs
vendored
Normal file
301
zeroidc/vendor/ring/src/aead/aes_gcm.rs
vendored
Normal file
@@ -0,0 +1,301 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::{
|
||||
aes::{self, Counter},
|
||||
gcm, shift, Aad, Block, Direction, Nonce, Tag, BLOCK_LEN,
|
||||
};
|
||||
use crate::{aead, cpu, endian::*, error, polyfill};
|
||||
|
||||
/// AES-128 in GCM mode with 128-bit tags and 96 bit nonces.
|
||||
pub static AES_128_GCM: aead::Algorithm = aead::Algorithm {
|
||||
key_len: 16,
|
||||
init: init_128,
|
||||
seal: aes_gcm_seal,
|
||||
open: aes_gcm_open,
|
||||
id: aead::AlgorithmID::AES_128_GCM,
|
||||
max_input_len: AES_GCM_MAX_INPUT_LEN,
|
||||
};
|
||||
|
||||
/// AES-256 in GCM mode with 128-bit tags and 96 bit nonces.
|
||||
pub static AES_256_GCM: aead::Algorithm = aead::Algorithm {
|
||||
key_len: 32,
|
||||
init: init_256,
|
||||
seal: aes_gcm_seal,
|
||||
open: aes_gcm_open,
|
||||
id: aead::AlgorithmID::AES_256_GCM,
|
||||
max_input_len: AES_GCM_MAX_INPUT_LEN,
|
||||
};
|
||||
|
||||
pub struct Key {
|
||||
gcm_key: gcm::Key, // First because it has a large alignment requirement.
|
||||
aes_key: aes::Key,
|
||||
}
|
||||
|
||||
fn init_128(key: &[u8], cpu_features: cpu::Features) -> Result<aead::KeyInner, error::Unspecified> {
|
||||
init(key, aes::Variant::AES_128, cpu_features)
|
||||
}
|
||||
|
||||
fn init_256(key: &[u8], cpu_features: cpu::Features) -> Result<aead::KeyInner, error::Unspecified> {
|
||||
init(key, aes::Variant::AES_256, cpu_features)
|
||||
}
|
||||
|
||||
fn init(
|
||||
key: &[u8],
|
||||
variant: aes::Variant,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Result<aead::KeyInner, error::Unspecified> {
|
||||
let aes_key = aes::Key::new(key, variant, cpu_features)?;
|
||||
let gcm_key = gcm::Key::new(aes_key.encrypt_block(Block::zero()), cpu_features);
|
||||
Ok(aead::KeyInner::AesGcm(Key { aes_key, gcm_key }))
|
||||
}
|
||||
|
||||
const CHUNK_BLOCKS: usize = 3 * 1024 / 16;
|
||||
|
||||
fn aes_gcm_seal(
|
||||
key: &aead::KeyInner,
|
||||
nonce: Nonce,
|
||||
aad: Aad<&[u8]>,
|
||||
in_out: &mut [u8],
|
||||
cpu_features: cpu::Features,
|
||||
) -> Tag {
|
||||
aead(key, nonce, aad, in_out, Direction::Sealing, cpu_features)
|
||||
}
|
||||
|
||||
fn aes_gcm_open(
|
||||
key: &aead::KeyInner,
|
||||
nonce: Nonce,
|
||||
aad: Aad<&[u8]>,
|
||||
in_prefix_len: usize,
|
||||
in_out: &mut [u8],
|
||||
cpu_features: cpu::Features,
|
||||
) -> Tag {
|
||||
aead(
|
||||
key,
|
||||
nonce,
|
||||
aad,
|
||||
in_out,
|
||||
Direction::Opening { in_prefix_len },
|
||||
cpu_features,
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)] // Avoid branching on `direction`.
|
||||
fn aead(
|
||||
key: &aead::KeyInner,
|
||||
nonce: Nonce,
|
||||
aad: Aad<&[u8]>,
|
||||
in_out: &mut [u8],
|
||||
direction: Direction,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Tag {
|
||||
let Key { aes_key, gcm_key } = match key {
|
||||
aead::KeyInner::AesGcm(key) => key,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut ctr = Counter::one(nonce);
|
||||
let tag_iv = ctr.increment();
|
||||
|
||||
let aad_len = aad.0.len();
|
||||
let mut gcm_ctx = gcm::Context::new(gcm_key, aad, cpu_features);
|
||||
|
||||
let in_prefix_len = match direction {
|
||||
Direction::Opening { in_prefix_len } => in_prefix_len,
|
||||
Direction::Sealing => 0,
|
||||
};
|
||||
|
||||
let total_in_out_len = in_out.len() - in_prefix_len;
|
||||
|
||||
let in_out = integrated_aes_gcm(
|
||||
aes_key,
|
||||
&mut gcm_ctx,
|
||||
in_out,
|
||||
&mut ctr,
|
||||
direction,
|
||||
cpu_features,
|
||||
);
|
||||
let in_out_len = in_out.len() - in_prefix_len;
|
||||
|
||||
// Process any (remaining) whole blocks.
|
||||
let whole_len = in_out_len - (in_out_len % BLOCK_LEN);
|
||||
{
|
||||
let mut chunk_len = CHUNK_BLOCKS * BLOCK_LEN;
|
||||
let mut output = 0;
|
||||
let mut input = in_prefix_len;
|
||||
loop {
|
||||
if whole_len - output < chunk_len {
|
||||
chunk_len = whole_len - output;
|
||||
}
|
||||
if chunk_len == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
if let Direction::Opening { .. } = direction {
|
||||
gcm_ctx.update_blocks(&in_out[input..][..chunk_len]);
|
||||
}
|
||||
|
||||
aes_key.ctr32_encrypt_blocks(
|
||||
&mut in_out[output..][..(chunk_len + in_prefix_len)],
|
||||
direction,
|
||||
&mut ctr,
|
||||
);
|
||||
|
||||
if let Direction::Sealing = direction {
|
||||
gcm_ctx.update_blocks(&in_out[output..][..chunk_len]);
|
||||
}
|
||||
|
||||
output += chunk_len;
|
||||
input += chunk_len;
|
||||
}
|
||||
}
|
||||
|
||||
// Process any remaining partial block.
|
||||
let remainder = &mut in_out[whole_len..];
|
||||
shift::shift_partial((in_prefix_len, remainder), |remainder| {
|
||||
let mut input = Block::zero();
|
||||
input.overwrite_part_at(0, remainder);
|
||||
if let Direction::Opening { .. } = direction {
|
||||
gcm_ctx.update_block(input);
|
||||
}
|
||||
let mut output = aes_key.encrypt_iv_xor_block(ctr.into(), input);
|
||||
if let Direction::Sealing = direction {
|
||||
output.zero_from(remainder.len());
|
||||
gcm_ctx.update_block(output);
|
||||
}
|
||||
output
|
||||
});
|
||||
|
||||
// Authenticate the final block containing the input lengths.
|
||||
let aad_bits = polyfill::u64_from_usize(aad_len) << 3;
|
||||
let ciphertext_bits = polyfill::u64_from_usize(total_in_out_len) << 3;
|
||||
gcm_ctx.update_block(Block::from_u64_be(
|
||||
BigEndian::from(aad_bits),
|
||||
BigEndian::from(ciphertext_bits),
|
||||
));
|
||||
|
||||
// Finalize the tag and return it.
|
||||
gcm_ctx.pre_finish(|pre_tag| {
|
||||
let bytes = tag_iv.into_bytes_less_safe();
|
||||
let mut tag = aes_key.encrypt_block(Block::from(&bytes));
|
||||
tag.bitxor_assign(pre_tag.into());
|
||||
Tag(*tag.as_ref())
|
||||
})
|
||||
}
|
||||
|
||||
// Returns the data that wasn't processed.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[inline] // Optimize out the match on `direction`.
|
||||
fn integrated_aes_gcm<'a>(
|
||||
aes_key: &aes::Key,
|
||||
gcm_ctx: &mut gcm::Context,
|
||||
in_out: &'a mut [u8],
|
||||
ctr: &mut Counter,
|
||||
direction: Direction,
|
||||
cpu_features: cpu::Features,
|
||||
) -> &'a mut [u8] {
|
||||
use crate::c;
|
||||
|
||||
if !aes_key.is_aes_hw() || !gcm_ctx.is_avx2(cpu_features) {
|
||||
return in_out;
|
||||
}
|
||||
|
||||
let processed = match direction {
|
||||
Direction::Opening { in_prefix_len } => {
|
||||
extern "C" {
|
||||
fn GFp_aesni_gcm_decrypt(
|
||||
input: *const u8,
|
||||
output: *mut u8,
|
||||
len: c::size_t,
|
||||
key: &aes::AES_KEY,
|
||||
ivec: &mut Counter,
|
||||
gcm: &mut gcm::ContextInner,
|
||||
) -> c::size_t;
|
||||
}
|
||||
unsafe {
|
||||
GFp_aesni_gcm_decrypt(
|
||||
in_out[in_prefix_len..].as_ptr(),
|
||||
in_out.as_mut_ptr(),
|
||||
in_out.len() - in_prefix_len,
|
||||
aes_key.inner_less_safe(),
|
||||
ctr,
|
||||
gcm_ctx.inner(),
|
||||
)
|
||||
}
|
||||
}
|
||||
Direction::Sealing => {
|
||||
extern "C" {
|
||||
fn GFp_aesni_gcm_encrypt(
|
||||
input: *const u8,
|
||||
output: *mut u8,
|
||||
len: c::size_t,
|
||||
key: &aes::AES_KEY,
|
||||
ivec: &mut Counter,
|
||||
gcm: &mut gcm::ContextInner,
|
||||
) -> c::size_t;
|
||||
}
|
||||
unsafe {
|
||||
GFp_aesni_gcm_encrypt(
|
||||
in_out.as_ptr(),
|
||||
in_out.as_mut_ptr(),
|
||||
in_out.len(),
|
||||
aes_key.inner_less_safe(),
|
||||
ctr,
|
||||
gcm_ctx.inner(),
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
&mut in_out[processed..]
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
#[inline]
|
||||
fn integrated_aes_gcm<'a>(
|
||||
_: &aes::Key,
|
||||
_: &mut gcm::Context,
|
||||
in_out: &'a mut [u8],
|
||||
_: &mut Counter,
|
||||
_: Direction,
|
||||
_: cpu::Features,
|
||||
) -> &'a mut [u8] {
|
||||
in_out // This doesn't process any of the input so it all remains.
|
||||
}
|
||||
|
||||
const AES_GCM_MAX_INPUT_LEN: u64 = super::max_input_len(BLOCK_LEN, 2);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn max_input_len_test() {
|
||||
// [NIST SP800-38D] Section 5.2.1.1. Note that [RFC 5116 Section 5.1] and
|
||||
// [RFC 5116 Section 5.2] have an off-by-one error in `P_MAX`.
|
||||
//
|
||||
// [NIST SP800-38D]:
|
||||
// http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
|
||||
// [RFC 5116 Section 5.1]: https://tools.ietf.org/html/rfc5116#section-5.1
|
||||
// [RFC 5116 Section 5.2]: https://tools.ietf.org/html/rfc5116#section-5.2
|
||||
const NIST_SP800_38D_MAX_BITS: u64 = (1u64 << 39) - 256;
|
||||
assert_eq!(NIST_SP800_38D_MAX_BITS, 549_755_813_632u64);
|
||||
assert_eq!(
|
||||
super::AES_128_GCM.max_input_len * 8,
|
||||
NIST_SP800_38D_MAX_BITS
|
||||
);
|
||||
assert_eq!(
|
||||
super::AES_256_GCM.max_input_len * 8,
|
||||
NIST_SP800_38D_MAX_BITS
|
||||
);
|
||||
}
|
||||
}
|
||||
7
zeroidc/vendor/ring/src/aead/aes_tests.txt
vendored
Normal file
7
zeroidc/vendor/ring/src/aead/aes_tests.txt
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
Key = 000102030405060708090a0b0c0d0e0f
|
||||
Input = 00112233445566778899aabbccddeeff
|
||||
Output = 69c4e0d86a7b0430d8cdb78070b4c55a
|
||||
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 00112233445566778899aabbccddeeff
|
||||
Output = 8ea2b7ca516745bfeafc49904b496089
|
||||
122
zeroidc/vendor/ring/src/aead/block.rs
vendored
Normal file
122
zeroidc/vendor/ring/src/aead/block.rs
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use crate::{endian::*, polyfill};
|
||||
|
||||
/// An array of 16 bytes that can (in the x86_64 and AAarch64 ABIs, at least)
|
||||
/// be efficiently passed by value and returned by value (i.e. in registers),
|
||||
/// and which meets the alignment requirements of `u32` and `u64` (at least)
|
||||
/// for the target.
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Block {
|
||||
subblocks: [u64; 2],
|
||||
}
|
||||
|
||||
pub const BLOCK_LEN: usize = 16;
|
||||
|
||||
impl Block {
|
||||
#[inline]
|
||||
pub fn zero() -> Self {
|
||||
Self { subblocks: [0, 0] }
|
||||
}
|
||||
|
||||
// TODO: Remove this.
|
||||
#[inline]
|
||||
pub fn from_u64_le(first: LittleEndian<u64>, second: LittleEndian<u64>) -> Self {
|
||||
#[allow(deprecated)]
|
||||
Self {
|
||||
subblocks: [first.into_raw_value(), second.into_raw_value()],
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove this.
|
||||
#[inline]
|
||||
pub fn from_u64_be(first: BigEndian<u64>, second: BigEndian<u64>) -> Self {
|
||||
#[allow(deprecated)]
|
||||
Self {
|
||||
subblocks: [first.into_raw_value(), second.into_raw_value()],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn u64s_be_to_native(&self) -> [u64; 2] {
|
||||
[
|
||||
u64::from_be(self.subblocks[0]),
|
||||
u64::from_be(self.subblocks[1]),
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn overwrite_part_at(&mut self, index: usize, a: &[u8]) {
|
||||
let mut tmp: [u8; BLOCK_LEN] = *self.as_ref();
|
||||
tmp[index..][..a.len()].copy_from_slice(a);
|
||||
*self = Self::from(&tmp)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn zero_from(&mut self, index: usize) {
|
||||
let mut tmp: [u8; BLOCK_LEN] = *self.as_ref();
|
||||
polyfill::slice::fill(&mut tmp[index..], 0);
|
||||
*self = Self::from(&tmp)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bitxor_assign(&mut self, a: Block) {
|
||||
for (r, a) in self.subblocks.iter_mut().zip(a.subblocks.iter()) {
|
||||
*r ^= *a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'_ [u8; BLOCK_LEN]> for Block {
|
||||
#[inline]
|
||||
fn from(bytes: &[u8; BLOCK_LEN]) -> Self {
|
||||
unsafe { core::mem::transmute_copy(bytes) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8; BLOCK_LEN]> for Block {
|
||||
#[allow(clippy::transmute_ptr_to_ptr)]
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[u8; BLOCK_LEN] {
|
||||
unsafe { core::mem::transmute(self) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_bitxor_assign() {
|
||||
const ONES: u64 = -1i64 as u64;
|
||||
const TEST_CASES: &[([u64; 2], [u64; 2], [u64; 2])] = &[
|
||||
([0, 0], [0, 0], [0, 0]),
|
||||
([0, 0], [ONES, ONES], [ONES, ONES]),
|
||||
([0, ONES], [ONES, 0], [ONES, ONES]),
|
||||
([ONES, 0], [0, ONES], [ONES, ONES]),
|
||||
([ONES, ONES], [ONES, ONES], [0, 0]),
|
||||
];
|
||||
for (expected_result, a, b) in TEST_CASES {
|
||||
let mut r = Block::from_u64_le(a[0].into(), a[1].into());
|
||||
r.bitxor_assign(Block::from_u64_le(b[0].into(), b[1].into()));
|
||||
assert_eq!(*expected_result, r.subblocks);
|
||||
|
||||
// XOR is symmetric.
|
||||
let mut r = Block::from_u64_le(b[0].into(), b[1].into());
|
||||
r.bitxor_assign(Block::from_u64_le(a[0].into(), a[1].into()));
|
||||
assert_eq!(*expected_result, r.subblocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
235
zeroidc/vendor/ring/src/aead/chacha.rs
vendored
Normal file
235
zeroidc/vendor/ring/src/aead/chacha.rs
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
// Portions Copyright (c) 2016, Google Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::{counter, iv::Iv, quic::Sample, BLOCK_LEN};
|
||||
use crate::{c, endian::*};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Key([LittleEndian<u32>; KEY_LEN / 4]);
|
||||
|
||||
impl From<[u8; KEY_LEN]> for Key {
|
||||
#[inline]
|
||||
fn from(value: [u8; KEY_LEN]) -> Self {
|
||||
Self(FromByteArray::from_byte_array(&value))
|
||||
}
|
||||
}
|
||||
|
||||
impl Key {
|
||||
#[inline] // Optimize away match on `counter`.
|
||||
pub fn encrypt_in_place(&self, counter: Counter, in_out: &mut [u8]) {
|
||||
unsafe {
|
||||
self.encrypt(
|
||||
CounterOrIv::Counter(counter),
|
||||
in_out.as_ptr(),
|
||||
in_out.len(),
|
||||
in_out.as_mut_ptr(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline] // Optimize away match on `iv` and length check.
|
||||
pub fn encrypt_iv_xor_blocks_in_place(&self, iv: Iv, in_out: &mut [u8; 2 * BLOCK_LEN]) {
|
||||
unsafe {
|
||||
self.encrypt(
|
||||
CounterOrIv::Iv(iv),
|
||||
in_out.as_ptr(),
|
||||
in_out.len(),
|
||||
in_out.as_mut_ptr(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_mask(&self, sample: Sample) -> [u8; 5] {
|
||||
let mut out: [u8; 5] = [0; 5];
|
||||
let iv = Iv::assume_unique_for_key(sample);
|
||||
|
||||
unsafe {
|
||||
self.encrypt(
|
||||
CounterOrIv::Iv(iv),
|
||||
out.as_ptr(),
|
||||
out.len(),
|
||||
out.as_mut_ptr(),
|
||||
);
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
pub fn encrypt_overlapping(&self, counter: Counter, in_out: &mut [u8], in_prefix_len: usize) {
|
||||
// XXX: The x86 and at least one branch of the ARM assembly language
|
||||
// code doesn't allow overlapping input and output unless they are
|
||||
// exactly overlapping. TODO: Figure out which branch of the ARM code
|
||||
// has this limitation and come up with a better solution.
|
||||
//
|
||||
// https://rt.openssl.org/Ticket/Display.html?id=4362
|
||||
let len = in_out.len() - in_prefix_len;
|
||||
if cfg!(any(target_arch = "arm", target_arch = "x86")) && in_prefix_len != 0 {
|
||||
in_out.copy_within(in_prefix_len.., 0);
|
||||
self.encrypt_in_place(counter, &mut in_out[..len]);
|
||||
} else {
|
||||
unsafe {
|
||||
self.encrypt(
|
||||
CounterOrIv::Counter(counter),
|
||||
in_out[in_prefix_len..].as_ptr(),
|
||||
len,
|
||||
in_out.as_mut_ptr(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline] // Optimize away match on `counter.`
|
||||
unsafe fn encrypt(
|
||||
&self,
|
||||
counter: CounterOrIv,
|
||||
input: *const u8,
|
||||
in_out_len: usize,
|
||||
output: *mut u8,
|
||||
) {
|
||||
let iv = match counter {
|
||||
CounterOrIv::Counter(counter) => counter.into(),
|
||||
CounterOrIv::Iv(iv) => {
|
||||
assert!(in_out_len <= 32);
|
||||
iv
|
||||
}
|
||||
};
|
||||
|
||||
/// XXX: Although this takes an `Iv`, this actually uses it like a
|
||||
/// `Counter`.
|
||||
extern "C" {
|
||||
fn GFp_ChaCha20_ctr32(
|
||||
out: *mut u8,
|
||||
in_: *const u8,
|
||||
in_len: c::size_t,
|
||||
key: &Key,
|
||||
first_iv: &Iv,
|
||||
);
|
||||
}
|
||||
|
||||
GFp_ChaCha20_ctr32(output, input, in_out_len, self, &iv);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[inline]
|
||||
pub(super) fn words_less_safe(&self) -> &[LittleEndian<u32>; KEY_LEN / 4] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub type Counter = counter::Counter<LittleEndian<u32>>;
|
||||
|
||||
enum CounterOrIv {
|
||||
Counter(Counter),
|
||||
Iv(Iv),
|
||||
}
|
||||
|
||||
const KEY_BLOCKS: usize = 2;
|
||||
pub const KEY_LEN: usize = KEY_BLOCKS * BLOCK_LEN;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test;
|
||||
use alloc::vec;
|
||||
use core::convert::TryInto;
|
||||
|
||||
// This verifies the encryption functionality provided by ChaCha20_ctr32
|
||||
// is successful when either computed on disjoint input/output buffers,
|
||||
// or on overlapping input/output buffers. On some branches of the 32-bit
|
||||
// x86 and ARM code the in-place operation fails in some situations where
|
||||
// the input/output buffers are not exactly overlapping. Such failures are
|
||||
// dependent not only on the degree of overlapping but also the length of
|
||||
// the data. `open()` works around that by moving the input data to the
|
||||
// output location so that the buffers exactly overlap, for those targets.
|
||||
// This test exists largely as a canary for detecting if/when that type of
|
||||
// problem spreads to other platforms.
|
||||
#[test]
|
||||
pub fn chacha20_tests() {
|
||||
test::run(test_file!("chacha_tests.txt"), |section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let key = test_case.consume_bytes("Key");
|
||||
let key: &[u8; KEY_LEN] = key.as_slice().try_into()?;
|
||||
let key = Key::from(*key);
|
||||
|
||||
let ctr = test_case.consume_usize("Ctr");
|
||||
let nonce = test_case.consume_bytes("Nonce");
|
||||
let input = test_case.consume_bytes("Input");
|
||||
let output = test_case.consume_bytes("Output");
|
||||
|
||||
// Pre-allocate buffer for use in test_cases.
|
||||
let mut in_out_buf = vec![0u8; input.len() + 276];
|
||||
|
||||
// Run the test case over all prefixes of the input because the
|
||||
// behavior of ChaCha20 implementation changes dependent on the
|
||||
// length of the input.
|
||||
for len in 0..(input.len() + 1) {
|
||||
chacha20_test_case_inner(
|
||||
&key,
|
||||
&nonce,
|
||||
ctr as u32,
|
||||
&input[..len],
|
||||
&output[..len],
|
||||
len,
|
||||
&mut in_out_buf,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
fn chacha20_test_case_inner(
|
||||
key: &Key,
|
||||
nonce: &[u8],
|
||||
ctr: u32,
|
||||
input: &[u8],
|
||||
expected: &[u8],
|
||||
len: usize,
|
||||
in_out_buf: &mut [u8],
|
||||
) {
|
||||
// Straightforward encryption into disjoint buffers is computed
|
||||
// correctly.
|
||||
unsafe {
|
||||
key.encrypt(
|
||||
CounterOrIv::Counter(Counter::from_test_vector(nonce, ctr)),
|
||||
input[..len].as_ptr(),
|
||||
len,
|
||||
in_out_buf.as_mut_ptr(),
|
||||
);
|
||||
}
|
||||
assert_eq!(&in_out_buf[..len], expected);
|
||||
|
||||
// Do not test offset buffers for x86 and ARM architectures (see above
|
||||
// for rationale).
|
||||
let max_offset = if cfg!(any(target_arch = "x86", target_arch = "arm")) {
|
||||
0
|
||||
} else {
|
||||
259
|
||||
};
|
||||
|
||||
// Check that in-place encryption works successfully when the pointers
|
||||
// to the input/output buffers are (partially) overlapping.
|
||||
for alignment in 0..16 {
|
||||
for offset in 0..(max_offset + 1) {
|
||||
in_out_buf[alignment + offset..][..len].copy_from_slice(input);
|
||||
let ctr = Counter::from_test_vector(nonce, ctr);
|
||||
key.encrypt_overlapping(ctr, &mut in_out_buf[alignment..], offset);
|
||||
assert_eq!(&in_out_buf[alignment..][..len], expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
291
zeroidc/vendor/ring/src/aead/chacha20_poly1305.rs
vendored
Normal file
291
zeroidc/vendor/ring/src/aead/chacha20_poly1305.rs
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::{
|
||||
chacha::{self, Counter},
|
||||
iv::Iv,
|
||||
poly1305, Aad, Block, Direction, Nonce, Tag, BLOCK_LEN,
|
||||
};
|
||||
use crate::{aead, cpu, endian::*, error, polyfill};
|
||||
use core::convert::TryInto;
|
||||
|
||||
/// ChaCha20-Poly1305 as described in [RFC 7539].
|
||||
///
|
||||
/// The keys are 256 bits long and the nonces are 96 bits long.
|
||||
///
|
||||
/// [RFC 7539]: https://tools.ietf.org/html/rfc7539
|
||||
pub static CHACHA20_POLY1305: aead::Algorithm = aead::Algorithm {
|
||||
key_len: chacha::KEY_LEN,
|
||||
init: chacha20_poly1305_init,
|
||||
seal: chacha20_poly1305_seal,
|
||||
open: chacha20_poly1305_open,
|
||||
id: aead::AlgorithmID::CHACHA20_POLY1305,
|
||||
max_input_len: super::max_input_len(64, 1),
|
||||
};
|
||||
|
||||
/// Copies |key| into |ctx_buf|.
|
||||
fn chacha20_poly1305_init(
|
||||
key: &[u8],
|
||||
_todo: cpu::Features,
|
||||
) -> Result<aead::KeyInner, error::Unspecified> {
|
||||
let key: [u8; chacha::KEY_LEN] = key.try_into()?;
|
||||
Ok(aead::KeyInner::ChaCha20Poly1305(chacha::Key::from(key)))
|
||||
}
|
||||
|
||||
fn chacha20_poly1305_seal(
|
||||
key: &aead::KeyInner,
|
||||
nonce: Nonce,
|
||||
aad: Aad<&[u8]>,
|
||||
in_out: &mut [u8],
|
||||
cpu_features: cpu::Features,
|
||||
) -> Tag {
|
||||
let key = match key {
|
||||
aead::KeyInner::ChaCha20Poly1305(key) => key,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
if cpu::intel::SSE41.available(cpu_features) {
|
||||
// XXX: BoringSSL uses `alignas(16)` on `key` instead of on the
|
||||
// structure, but Rust can't do that yet; see
|
||||
// https://github.com/rust-lang/rust/issues/73557.
|
||||
//
|
||||
// Keep in sync with the anonymous struct of BoringSSL's
|
||||
// `chacha20_poly1305_seal_data`.
|
||||
#[repr(align(16), C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct seal_data_in {
|
||||
key: [u8; chacha::KEY_LEN],
|
||||
counter: u32,
|
||||
nonce: [u8; super::NONCE_LEN],
|
||||
extra_ciphertext: *const u8,
|
||||
extra_ciphertext_len: usize,
|
||||
}
|
||||
|
||||
let mut data = InOut {
|
||||
input: seal_data_in {
|
||||
key: *key.words_less_safe().as_byte_array(),
|
||||
counter: 0,
|
||||
nonce: *nonce.as_ref(),
|
||||
extra_ciphertext: core::ptr::null(),
|
||||
extra_ciphertext_len: 0,
|
||||
},
|
||||
};
|
||||
|
||||
// Encrypts `plaintext_len` bytes from `plaintext` and writes them to `out_ciphertext`.
|
||||
extern "C" {
|
||||
fn GFp_chacha20_poly1305_seal(
|
||||
out_ciphertext: *mut u8,
|
||||
plaintext: *const u8,
|
||||
plaintext_len: usize,
|
||||
ad: *const u8,
|
||||
ad_len: usize,
|
||||
data: &mut InOut<seal_data_in>,
|
||||
);
|
||||
}
|
||||
|
||||
let out = unsafe {
|
||||
GFp_chacha20_poly1305_seal(
|
||||
in_out.as_mut_ptr(),
|
||||
in_out.as_ptr(),
|
||||
in_out.len(),
|
||||
aad.as_ref().as_ptr(),
|
||||
aad.as_ref().len(),
|
||||
&mut data,
|
||||
);
|
||||
&data.out
|
||||
};
|
||||
|
||||
return Tag(out.tag);
|
||||
}
|
||||
}
|
||||
|
||||
aead(key, nonce, aad, in_out, Direction::Sealing, cpu_features)
|
||||
}
|
||||
|
||||
fn chacha20_poly1305_open(
|
||||
key: &aead::KeyInner,
|
||||
nonce: Nonce,
|
||||
aad: Aad<&[u8]>,
|
||||
in_prefix_len: usize,
|
||||
in_out: &mut [u8],
|
||||
cpu_features: cpu::Features,
|
||||
) -> Tag {
|
||||
let key = match key {
|
||||
aead::KeyInner::ChaCha20Poly1305(key) => key,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
if cpu::intel::SSE41.available(cpu_features) {
|
||||
// XXX: BoringSSL uses `alignas(16)` on `key` instead of on the
|
||||
// structure, but Rust can't do that yet; see
|
||||
// https://github.com/rust-lang/rust/issues/73557.
|
||||
//
|
||||
// Keep in sync with the anonymous struct of BoringSSL's
|
||||
// `chacha20_poly1305_open_data`.
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(align(16), C)]
|
||||
struct open_data_in {
|
||||
key: [u8; chacha::KEY_LEN],
|
||||
counter: u32,
|
||||
nonce: [u8; super::NONCE_LEN],
|
||||
}
|
||||
|
||||
let mut data = InOut {
|
||||
input: open_data_in {
|
||||
key: *key.words_less_safe().as_byte_array(),
|
||||
counter: 0,
|
||||
nonce: *nonce.as_ref(),
|
||||
},
|
||||
};
|
||||
|
||||
// Decrypts `plaintext_len` bytes from `ciphertext` and writes them to `out_plaintext`.
|
||||
extern "C" {
|
||||
fn GFp_chacha20_poly1305_open(
|
||||
out_plaintext: *mut u8,
|
||||
ciphertext: *const u8,
|
||||
plaintext_len: usize,
|
||||
ad: *const u8,
|
||||
ad_len: usize,
|
||||
data: &mut InOut<open_data_in>,
|
||||
);
|
||||
}
|
||||
|
||||
let out = unsafe {
|
||||
GFp_chacha20_poly1305_open(
|
||||
in_out.as_mut_ptr(),
|
||||
in_out.as_ptr().add(in_prefix_len),
|
||||
in_out.len() - in_prefix_len,
|
||||
aad.as_ref().as_ptr(),
|
||||
aad.as_ref().len(),
|
||||
&mut data,
|
||||
);
|
||||
&data.out
|
||||
};
|
||||
|
||||
return Tag(out.tag);
|
||||
}
|
||||
}
|
||||
|
||||
aead(
|
||||
key,
|
||||
nonce,
|
||||
aad,
|
||||
in_out,
|
||||
Direction::Opening { in_prefix_len },
|
||||
cpu_features,
|
||||
)
|
||||
}
|
||||
|
||||
pub type Key = chacha::Key;
|
||||
|
||||
// Keep in sync with BoringSSL's `chacha20_poly1305_open_data` and
|
||||
// `chacha20_poly1305_seal_data`.
|
||||
#[repr(C)]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
union InOut<T>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
input: T,
|
||||
out: Out,
|
||||
}
|
||||
|
||||
// It isn't obvious whether the assembly code works for tags that aren't
|
||||
// 16-byte aligned. In practice it will always be 16-byte aligned because it
|
||||
// is embedded in a union where the other member of the union is 16-byte
|
||||
// aligned.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(align(16), C)]
|
||||
struct Out {
|
||||
tag: [u8; super::TAG_LEN],
|
||||
}
|
||||
|
||||
#[inline(always)] // Statically eliminate branches on `direction`.
|
||||
fn aead(
|
||||
chacha20_key: &Key,
|
||||
nonce: Nonce,
|
||||
Aad(aad): Aad<&[u8]>,
|
||||
in_out: &mut [u8],
|
||||
direction: Direction,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Tag {
|
||||
let mut counter = Counter::zero(nonce);
|
||||
let mut ctx = {
|
||||
let key = derive_poly1305_key(chacha20_key, counter.increment(), cpu_features);
|
||||
poly1305::Context::from_key(key)
|
||||
};
|
||||
|
||||
poly1305_update_padded_16(&mut ctx, aad);
|
||||
|
||||
let in_out_len = match direction {
|
||||
Direction::Opening { in_prefix_len } => {
|
||||
poly1305_update_padded_16(&mut ctx, &in_out[in_prefix_len..]);
|
||||
chacha20_key.encrypt_overlapping(counter, in_out, in_prefix_len);
|
||||
in_out.len() - in_prefix_len
|
||||
}
|
||||
Direction::Sealing => {
|
||||
chacha20_key.encrypt_in_place(counter, in_out);
|
||||
poly1305_update_padded_16(&mut ctx, in_out);
|
||||
in_out.len()
|
||||
}
|
||||
};
|
||||
|
||||
ctx.update(
|
||||
Block::from_u64_le(
|
||||
LittleEndian::from(polyfill::u64_from_usize(aad.len())),
|
||||
LittleEndian::from(polyfill::u64_from_usize(in_out_len)),
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
ctx.finish()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poly1305_update_padded_16(ctx: &mut poly1305::Context, input: &[u8]) {
|
||||
let remainder_len = input.len() % BLOCK_LEN;
|
||||
let whole_len = input.len() - remainder_len;
|
||||
if whole_len > 0 {
|
||||
ctx.update(&input[..whole_len]);
|
||||
}
|
||||
if remainder_len > 0 {
|
||||
let mut block = Block::zero();
|
||||
block.overwrite_part_at(0, &input[whole_len..]);
|
||||
ctx.update(block.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
// Also used by chacha20_poly1305_openssh.
|
||||
pub(super) fn derive_poly1305_key(
|
||||
chacha_key: &chacha::Key,
|
||||
iv: Iv,
|
||||
cpu_features: cpu::Features,
|
||||
) -> poly1305::Key {
|
||||
let mut key_bytes = [0u8; 2 * BLOCK_LEN];
|
||||
chacha_key.encrypt_iv_xor_blocks_in_place(iv, &mut key_bytes);
|
||||
poly1305::Key::new(key_bytes, cpu_features)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn max_input_len_test() {
|
||||
// Errata 4858 at https://www.rfc-editor.org/errata_search.php?rfc=7539.
|
||||
assert_eq!(super::CHACHA20_POLY1305.max_input_len, 274_877_906_880u64);
|
||||
}
|
||||
}
|
||||
189
zeroidc/vendor/ring/src/aead/chacha20_poly1305_openssh.rs
vendored
Normal file
189
zeroidc/vendor/ring/src/aead/chacha20_poly1305_openssh.rs
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! The [chacha20-poly1305@openssh.com] AEAD-ish construct.
|
||||
//!
|
||||
//! This should only be used by SSH implementations. It has a similar, but
|
||||
//! different API from `ring::aead` because the construct cannot use the same
|
||||
//! API as `ring::aead` due to the way the construct handles the encrypted
|
||||
//! packet length.
|
||||
//!
|
||||
//! The concatenation of a and b is denoted `a||b`. `K_1` and `K_2` are defined
|
||||
//! in the [chacha20-poly1305@openssh.com] specification. `packet_length`,
|
||||
//! `padding_length`, `payload`, and `random padding` are defined in
|
||||
//! [RFC 4253]. The term `plaintext` is used as a shorthand for
|
||||
//! `padding_length||payload||random padding`.
|
||||
//!
|
||||
//! [chacha20-poly1305@openssh.com]:
|
||||
//! http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.chacha20poly1305?annotate=HEAD
|
||||
//! [RFC 4253]: https://tools.ietf.org/html/rfc4253
|
||||
|
||||
use super::{
|
||||
chacha::{self, *},
|
||||
chacha20_poly1305::derive_poly1305_key,
|
||||
cpu, poly1305, Nonce, Tag,
|
||||
};
|
||||
use crate::{constant_time, endian::*, error};
|
||||
use core::convert::TryInto;
|
||||
|
||||
/// A key for sealing packets.
|
||||
pub struct SealingKey {
|
||||
key: Key,
|
||||
}
|
||||
|
||||
impl SealingKey {
|
||||
/// Constructs a new `SealingKey`.
|
||||
pub fn new(key_material: &[u8; KEY_LEN]) -> SealingKey {
|
||||
SealingKey {
|
||||
key: Key::new(key_material, cpu::features()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Seals (encrypts and signs) a packet.
|
||||
///
|
||||
/// On input, `plaintext_in_ciphertext_out` must contain the unencrypted
|
||||
/// `packet_length||plaintext` where `plaintext` is the
|
||||
/// `padding_length||payload||random padding`. It will be overwritten by
|
||||
/// `encrypted_packet_length||ciphertext`, where `encrypted_packet_length`
|
||||
/// is encrypted with `K_1` and `ciphertext` is encrypted by `K_2`.
|
||||
pub fn seal_in_place(
|
||||
&self,
|
||||
sequence_number: u32,
|
||||
plaintext_in_ciphertext_out: &mut [u8],
|
||||
tag_out: &mut [u8; TAG_LEN],
|
||||
) {
|
||||
let mut counter = make_counter(sequence_number);
|
||||
let poly_key =
|
||||
derive_poly1305_key(&self.key.k_2, counter.increment(), self.key.cpu_features);
|
||||
|
||||
{
|
||||
let (len_in_out, data_and_padding_in_out) =
|
||||
plaintext_in_ciphertext_out.split_at_mut(PACKET_LENGTH_LEN);
|
||||
|
||||
self.key
|
||||
.k_1
|
||||
.encrypt_in_place(make_counter(sequence_number), len_in_out);
|
||||
self.key
|
||||
.k_2
|
||||
.encrypt_in_place(counter, data_and_padding_in_out);
|
||||
}
|
||||
|
||||
let Tag(tag) = poly1305::sign(poly_key, plaintext_in_ciphertext_out);
|
||||
tag_out.copy_from_slice(tag.as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
/// A key for opening packets.
|
||||
pub struct OpeningKey {
|
||||
key: Key,
|
||||
}
|
||||
|
||||
impl OpeningKey {
|
||||
/// Constructs a new `OpeningKey`.
|
||||
pub fn new(key_material: &[u8; KEY_LEN]) -> OpeningKey {
|
||||
OpeningKey {
|
||||
key: Key::new(key_material, cpu::features()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the decrypted, but unauthenticated, packet length.
|
||||
///
|
||||
/// Importantly, the result won't be authenticated until `open_in_place` is
|
||||
/// called.
|
||||
pub fn decrypt_packet_length(
|
||||
&self,
|
||||
sequence_number: u32,
|
||||
encrypted_packet_length: [u8; PACKET_LENGTH_LEN],
|
||||
) -> [u8; PACKET_LENGTH_LEN] {
|
||||
let mut packet_length = encrypted_packet_length;
|
||||
let counter = make_counter(sequence_number);
|
||||
self.key.k_1.encrypt_in_place(counter, &mut packet_length);
|
||||
packet_length
|
||||
}
|
||||
|
||||
/// Opens (authenticates and decrypts) a packet.
|
||||
///
|
||||
/// `ciphertext_in_plaintext_out` must be of the form
|
||||
/// `encrypted_packet_length||ciphertext` where `ciphertext` is the
|
||||
/// encrypted `plaintext`. When the function succeeds the ciphertext is
|
||||
/// replaced by the plaintext and the result is `Ok(plaintext)`, where
|
||||
/// `plaintext` is `&ciphertext_in_plaintext_out[PACKET_LENGTH_LEN..]`;
|
||||
/// otherwise the contents of `ciphertext_in_plaintext_out` are unspecified
|
||||
/// and must not be used.
|
||||
pub fn open_in_place<'a>(
|
||||
&self,
|
||||
sequence_number: u32,
|
||||
ciphertext_in_plaintext_out: &'a mut [u8],
|
||||
tag: &[u8; TAG_LEN],
|
||||
) -> Result<&'a [u8], error::Unspecified> {
|
||||
let mut counter = make_counter(sequence_number);
|
||||
|
||||
// We must verify the tag before decrypting so that
|
||||
// `ciphertext_in_plaintext_out` is unmodified if verification fails.
|
||||
// This is beyond what we guarantee.
|
||||
let poly_key =
|
||||
derive_poly1305_key(&self.key.k_2, counter.increment(), self.key.cpu_features);
|
||||
verify(poly_key, ciphertext_in_plaintext_out, tag)?;
|
||||
|
||||
let plaintext_in_ciphertext_out = &mut ciphertext_in_plaintext_out[PACKET_LENGTH_LEN..];
|
||||
self.key
|
||||
.k_2
|
||||
.encrypt_in_place(counter, plaintext_in_ciphertext_out);
|
||||
|
||||
Ok(plaintext_in_ciphertext_out)
|
||||
}
|
||||
}
|
||||
|
||||
struct Key {
|
||||
k_1: chacha::Key,
|
||||
k_2: chacha::Key,
|
||||
cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
impl Key {
|
||||
fn new(key_material: &[u8; KEY_LEN], cpu_features: cpu::Features) -> Key {
|
||||
// The first half becomes K_2 and the second half becomes K_1.
|
||||
let (k_2, k_1) = key_material.split_at(chacha::KEY_LEN);
|
||||
let k_1: [u8; chacha::KEY_LEN] = k_1.try_into().unwrap();
|
||||
let k_2: [u8; chacha::KEY_LEN] = k_2.try_into().unwrap();
|
||||
Key {
|
||||
k_1: chacha::Key::from(k_1),
|
||||
k_2: chacha::Key::from(k_2),
|
||||
cpu_features,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_counter(sequence_number: u32) -> Counter {
|
||||
let nonce = [
|
||||
BigEndian::ZERO,
|
||||
BigEndian::ZERO,
|
||||
BigEndian::from(sequence_number),
|
||||
];
|
||||
Counter::zero(Nonce::assume_unique_for_key(*(nonce.as_byte_array())))
|
||||
}
|
||||
|
||||
/// The length of key.
|
||||
pub const KEY_LEN: usize = chacha::KEY_LEN * 2;
|
||||
|
||||
/// The length in bytes of the `packet_length` field in a SSH packet.
|
||||
pub const PACKET_LENGTH_LEN: usize = 4; // 32 bits
|
||||
|
||||
/// The length in bytes of an authentication tag.
|
||||
pub const TAG_LEN: usize = super::BLOCK_LEN;
|
||||
|
||||
fn verify(key: poly1305::Key, msg: &[u8], tag: &[u8; TAG_LEN]) -> Result<(), error::Unspecified> {
|
||||
let Tag(calculated_tag) = poly1305::sign(key, msg);
|
||||
constant_time::verify_slices_are_equal(calculated_tag.as_ref(), tag)
|
||||
}
|
||||
5
zeroidc/vendor/ring/src/aead/chacha_tests.txt
vendored
Normal file
5
zeroidc/vendor/ring/src/aead/chacha_tests.txt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Key = 98bef1469be7269837a45bfbc92a5a6ac762507cf96443bf33b96b1bd4c6f8f6
|
||||
Ctr = 42
|
||||
Nonce = 44e792d63335abb1582e9253
|
||||
Input = 5828d530362c605529f8e18cae151526f23a73a0f312a3885f2b74233dc90523c654491e448814d9da3715dcb7e423b39d7e166835fc026dcc8ae5dd5fe4d2566f129c9c7d6a3848bddfd9ac1ba24dc543043cd799e1a7139c51c26df9cf073be4bf93a3a9b4c5f01ae48d5fc6c47c697ade1ac1c9cfc24e7a252c32e917ba68f1375d628446f5807f1a71f7be724bb81cfe3ebdae0d730d874a31c33d466fb3d76be3b870178e7a6a0ebfa8bc2bdbfa4fb62620ee63f06d26ac6a18376e5981d160e640d56d68ba8b654af9f1ae56248fe38ee77e6fcf92dfa9753ad62e1caff2d68b39add25dfbd7df05570df7f68f2d14b04e1a3c7704cd3c5c5852106fcf5c03c85f852b058260dacccdd688bfc010b36f545442bc4b77214dee8745064c6038d27e1d306c55f038801cde3dea683ef63e59cf0d08ae8c020bc1726ab46df3f7b3ef3ab106f2f4d6697b3ea216313179b633a9ca8aa8bef3e93828d1e13b4e2e4735a461141e422c4955eae3b3ce39d3b3ef4a4d7849bdf67c0a2cd326cbd96aad6393a72992dc1faf61828074b29c4a867350d8d1ffee1ae2dda261bd10c35f679f29e4d370e5673ad22000cc251596544585ed82883b9f3bc304d423b10ddcc8269d28b3254d52e533f3ed2cb81acfc352b42fc77996147d72277285ea6d41a022136d0683a4dd0f69d201cdc6b8645c2c79d1c7d331db2cffdad06931ad835fed6a97e40043b02e97ae005f5cb9e8398010ca0cfaf0b5cdaa271160d9218693919f2d1a8ede0bb5cb052430454d1175fde5a0a94e3a8c3b525a3718054a7a096ae6d5a9a671474c50e13e8a212b4f0ee3cb72c5283e5a33ec48922ea12457090f01853b34397ec79062e2dc5d0a2c5126953a9592a5398f0c830b9d38ab982ac401c40d7713cbcaf128315275272cf00486c8f33df29d8f5552403faa227fe7693bee4409deffb0693aae74e99d33ae8b6d6004ff533f88e9639bb16d2c22155a15d9e5cb03783cca598cc8c286ffd279d6c6ec5bbba0ae0120092e385dda5de0594ee58b848fb6e0569f21a1cfb20f2c93f8cf37c19f3298216552666ed3719855b9469f1a35c4476962704b779ee421e6325a2605ba5753d79b553cbb5379609cc84df7f51d540291680eaaca5a780c289ac3ac49c0f485ee59767e284ef15c63f7ce0e2c21a058e901fdebd1afe6ef93b3955160a2744015e5f40aca6d9a37424d5a58490fe902fc77d859deddad4b992e6473ad422ff32c0d49e42e6ca47375181485bb64b4a1b06e01c0cf179cc528c32d6c172a3d065cf3b44975ad1769d4ca65ae4471a5f60d0f8e37c743ce6b08e9d134488fc9fcf35d2dec62d3f0b3fe2e40557654c7b46116cc7c1c1924e64dd4c377671f3c7479a1f885881d6fa47e2c219f49f5aa4ef34afa9dbef6cedab5ab39bd1641a94aac0901ca
|
||||
Output = 54306a13da596b6d5949c8c5ab26d48aadc03daf14b915b8cadf17a703d3c50601ef21dda30b9e48b85e0b879f9523688569d25daf57e927113d49faf108cc15ec1d1916129bc8661ffa2c93f4991127310ed8464740117001cae85bc591c83adcaaf34b80e5bc03d08972bcce2a760cf5da4c10063541b1e6b4aa7aeff0624ac59f2cafb82fd9d1017a362f3e83a5eb8170a0571746ea9ecb0e74d344571d4006f8b7cb5ff479bd1119d6eef8b0aadd0062ad3b889a885b1b07c9ae9ea694e555db4523b92ccd29d354c3881e5f52f2090026261aedf5c2a97df9215aaf6dab8e168496b54fcf1ea3af089f7986c3be0c70cb8ff3c5f8e84b217d18a9ed8bfb6b5a6f260b56047cfe0e1ec13f82c573bd530cf0e2c9f33d1b6dba70c16db60028e1c4786204da2386c3da743d7cd67629b2272eb235426082cf302c59e4e3d0741f58e8da4745731c0593ae75be1f81d8b7b3fffc8b529eed8b379fe0b8a266e16ac51f1df0de3f3db028f3aa4e4d31b026792b080fe92f79b3c8dda789a8a81d590e4f1e931f707f4e7efeb8ca63e0a605ccd7de2a4931785c5f44b29b91991429630912dd02d97be9f51207d0e7e6e8dddaa473c48ebd7bb7bbcb832f43f61c50ae9b2e52801885a823527a6af74236ca915a3d2aa0357d70fc4c187c5772cf9b29d6d0b4d7e6897069225e45094d4987845f8a5fe415d3e372afb2309cc1ff8e6d2a769e08037ee0c3c297066b332b08e3d50bd832676110ed6bed50efd71c1be06da16419342fe4e854bf840edf0e8bd8dd7796b854abf295590d0d0a156e01f224aba0d8df38ea97587688beaf45e3564f68e84be72b22189682892534d1dd08ea7e21ef575543f7faca1cde992e8bd8c3cf894dfc3b7d4ac999c431b67aaef849b246c1600575f33df2c984a4b98a872a875c0abc517d9af5c9242d5ee6c6e3cd7ee4af8a6c0004c8d7a5adfab2084a269b7cd0c613b1b9653f7030f9989d879957713eb1c324f0a6a2609d66d25faee39487ead1ea0d2a77ef31ccebf90cdc9c1280bbb08eab9a04cd4b954f7a0b537c16cc0eb17310ddaa769490d98b664131ed8c7d74c433fac3438d10bc844d0e9532df17436dd25e12b9ed33d9976f4acdc3cd8134be7ea2d0a7915d90f65e4a250fcc24ebe1e4626c8f4536975dda202b86008c94a96a69b2e9bb828e4195b4b7f15552303948b32582a9102789b5e51fab723c7008cee661bf19c8902b29303eb84c33f0f0152eb725ca994b6f4b4150ee5699cf2ba4c47c5ca6d467045c5d5f269e0fe258684c30cdef46db376fbbc480ca8a545d719d0ce8b82c109044a4883fbc153cd2ca0ec3e46eefb0cbfd617c27f225ea716df7499c8127f06133cf5568d373a4ed35652af23ecf9098546d956a0c9c240eb4b79b8d6e1cbceb171086da916d894cebf5508f40cf4a
|
||||
105
zeroidc/vendor/ring/src/aead/counter.rs
vendored
Normal file
105
zeroidc/vendor/ring/src/aead/counter.rs
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::{
|
||||
iv::{Iv, IV_LEN},
|
||||
Nonce,
|
||||
};
|
||||
use crate::endian::*;
|
||||
use core::convert::TryInto;
|
||||
|
||||
/// A generator of a monotonically increasing series of `Iv`s.
|
||||
///
|
||||
/// Intentionally not `Clone` to ensure counters aren't forked.
|
||||
#[repr(C)]
|
||||
pub struct Counter<U32> {
|
||||
u32s: [U32; COUNTER_LEN],
|
||||
}
|
||||
|
||||
const COUNTER_LEN: usize = 4;
|
||||
|
||||
impl<U32> Counter<U32>
|
||||
where
|
||||
U32: Copy,
|
||||
U32: Encoding<u32>,
|
||||
U32: From<[u8; 4]>,
|
||||
U32: Layout,
|
||||
[U32; 4]: ArrayEncoding<[u8; IV_LEN]>,
|
||||
{
|
||||
pub fn zero(nonce: Nonce) -> Self {
|
||||
Self::new(nonce, 0)
|
||||
}
|
||||
pub fn one(nonce: Nonce) -> Self {
|
||||
Self::new(nonce, 1)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn from_test_vector(nonce: &[u8], initial_counter: u32) -> Self {
|
||||
Self::new(
|
||||
Nonce::try_assume_unique_for_key(nonce).unwrap(),
|
||||
initial_counter,
|
||||
)
|
||||
}
|
||||
|
||||
fn new(nonce: Nonce, initial_counter: u32) -> Self {
|
||||
let mut r = Self {
|
||||
u32s: [U32::ZERO; COUNTER_LEN],
|
||||
};
|
||||
let nonce_index = (U32::COUNTER_INDEX + 1) % COUNTER_LEN;
|
||||
(&mut r.u32s[nonce_index..][..3])
|
||||
.iter_mut()
|
||||
.zip(nonce.as_ref().chunks_exact(4))
|
||||
.for_each(|(initial, nonce)| {
|
||||
let nonce: &[u8; 4] = nonce.try_into().unwrap();
|
||||
*initial = U32::from(*nonce);
|
||||
});
|
||||
r.u32s[U32::COUNTER_INDEX] = U32::from(initial_counter);
|
||||
r
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn increment(&mut self) -> Iv {
|
||||
let current = Self { u32s: self.u32s };
|
||||
self.increment_by_less_safe(1);
|
||||
current.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn increment_by_less_safe(&mut self, increment_by: u32) {
|
||||
let counter = &mut self.u32s[U32::COUNTER_INDEX];
|
||||
let old_value: u32 = (*counter).into();
|
||||
*counter = U32::from(old_value + increment_by);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Layout {
|
||||
const COUNTER_INDEX: usize;
|
||||
}
|
||||
|
||||
impl Layout for BigEndian<u32> {
|
||||
const COUNTER_INDEX: usize = 3;
|
||||
}
|
||||
|
||||
impl Layout for LittleEndian<u32> {
|
||||
const COUNTER_INDEX: usize = 0;
|
||||
}
|
||||
|
||||
impl<U32> Into<Iv> for Counter<U32>
|
||||
where
|
||||
[U32; 4]: ArrayEncoding<[u8; IV_LEN]>,
|
||||
{
|
||||
fn into(self) -> Iv {
|
||||
Iv::assume_unique_for_key(*self.u32s.as_byte_array())
|
||||
}
|
||||
}
|
||||
340
zeroidc/vendor/ring/src/aead/gcm.rs
vendored
Normal file
340
zeroidc/vendor/ring/src/aead/gcm.rs
vendored
Normal file
@@ -0,0 +1,340 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::{Aad, Block, BLOCK_LEN};
|
||||
use crate::cpu;
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
mod gcm_nohw;
|
||||
|
||||
pub struct Key(HTable);
|
||||
|
||||
impl Key {
|
||||
pub(super) fn new(h_be: Block, cpu_features: cpu::Features) -> Self {
|
||||
let h = h_be.u64s_be_to_native();
|
||||
|
||||
let mut key = Self(HTable {
|
||||
Htable: [u128 { hi: 0, lo: 0 }; HTABLE_LEN],
|
||||
});
|
||||
let h_table = &mut key.0;
|
||||
|
||||
match detect_implementation(cpu_features) {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
Implementation::CLMUL if has_avx_movbe(cpu_features) => {
|
||||
extern "C" {
|
||||
fn GFp_gcm_init_avx(HTable: &mut HTable, h: &[u64; 2]);
|
||||
}
|
||||
unsafe {
|
||||
GFp_gcm_init_avx(h_table, &h);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
Implementation::CLMUL => {
|
||||
extern "C" {
|
||||
fn GFp_gcm_init_clmul(Htable: &mut HTable, h: &[u64; 2]);
|
||||
}
|
||||
unsafe {
|
||||
GFp_gcm_init_clmul(h_table, &h);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
|
||||
Implementation::NEON => {
|
||||
extern "C" {
|
||||
fn GFp_gcm_init_neon(Htable: &mut HTable, h: &[u64; 2]);
|
||||
}
|
||||
unsafe {
|
||||
GFp_gcm_init_neon(h_table, &h);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
Implementation::Fallback => {
|
||||
h_table.Htable[0] = gcm_nohw::init(h);
|
||||
}
|
||||
}
|
||||
|
||||
key
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
inner: ContextInner,
|
||||
cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub(crate) fn new(key: &Key, aad: Aad<&[u8]>, cpu_features: cpu::Features) -> Self {
|
||||
let mut ctx = Context {
|
||||
inner: ContextInner {
|
||||
Xi: Xi(Block::zero()),
|
||||
_unused: Block::zero(),
|
||||
Htable: key.0.clone(),
|
||||
},
|
||||
cpu_features,
|
||||
};
|
||||
|
||||
for ad in aad.0.chunks(BLOCK_LEN) {
|
||||
let mut block = Block::zero();
|
||||
block.overwrite_part_at(0, ad);
|
||||
ctx.update_block(block);
|
||||
}
|
||||
|
||||
ctx
|
||||
}
|
||||
|
||||
/// Access to `inner` for the integrated AES-GCM implementations only.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[inline]
|
||||
pub(super) fn inner(&mut self) -> &mut ContextInner {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
pub fn update_blocks(&mut self, input: &[u8]) {
|
||||
debug_assert!(input.len() > 0);
|
||||
debug_assert_eq!(input.len() % BLOCK_LEN, 0);
|
||||
|
||||
// Although these functions take `Xi` and `h_table` as separate
|
||||
// parameters, one or more of them might assume that they are part of
|
||||
// the same `ContextInner` structure.
|
||||
let xi = &mut self.inner.Xi;
|
||||
let h_table = &self.inner.Htable;
|
||||
|
||||
match detect_implementation(self.cpu_features) {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
Implementation::CLMUL if has_avx_movbe(self.cpu_features) => {
|
||||
extern "C" {
|
||||
fn GFp_gcm_ghash_avx(
|
||||
xi: &mut Xi,
|
||||
Htable: &HTable,
|
||||
inp: *const u8,
|
||||
len: crate::c::size_t,
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
GFp_gcm_ghash_avx(xi, h_table, input.as_ptr(), input.len());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
Implementation::CLMUL => {
|
||||
extern "C" {
|
||||
fn GFp_gcm_ghash_clmul(
|
||||
xi: &mut Xi,
|
||||
Htable: &HTable,
|
||||
inp: *const u8,
|
||||
len: crate::c::size_t,
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
GFp_gcm_ghash_clmul(xi, h_table, input.as_ptr(), input.len());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
|
||||
Implementation::NEON => {
|
||||
extern "C" {
|
||||
fn GFp_gcm_ghash_neon(
|
||||
xi: &mut Xi,
|
||||
Htable: &HTable,
|
||||
inp: *const u8,
|
||||
len: crate::c::size_t,
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
GFp_gcm_ghash_neon(xi, h_table, input.as_ptr(), input.len());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
Implementation::Fallback => {
|
||||
gcm_nohw::ghash(xi, h_table.Htable[0], input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_block(&mut self, a: Block) {
|
||||
self.inner.Xi.bitxor_assign(a);
|
||||
|
||||
// Although these functions take `Xi` and `h_table` as separate
|
||||
// parameters, one or more of them might assume that they are part of
|
||||
// the same `ContextInner` structure.
|
||||
let xi = &mut self.inner.Xi;
|
||||
let h_table = &self.inner.Htable;
|
||||
|
||||
match detect_implementation(self.cpu_features) {
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
Implementation::CLMUL => {
|
||||
extern "C" {
|
||||
fn GFp_gcm_gmult_clmul(xi: &mut Xi, Htable: &HTable);
|
||||
}
|
||||
unsafe {
|
||||
GFp_gcm_gmult_clmul(xi, h_table);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
|
||||
Implementation::NEON => {
|
||||
extern "C" {
|
||||
fn GFp_gcm_gmult_neon(xi: &mut Xi, Htable: &HTable);
|
||||
}
|
||||
unsafe {
|
||||
GFp_gcm_gmult_neon(xi, h_table);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
Implementation::Fallback => {
|
||||
gcm_nohw::gmult(xi, h_table.Htable[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn pre_finish<F>(self, f: F) -> super::Tag
|
||||
where
|
||||
F: FnOnce(Xi) -> super::Tag,
|
||||
{
|
||||
f(self.inner.Xi)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub(super) fn is_avx2(&self, cpu_features: cpu::Features) -> bool {
|
||||
match detect_implementation(cpu_features) {
|
||||
Implementation::CLMUL => has_avx_movbe(self.cpu_features),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The alignment is required by non-Rust code that uses `GCM128_CONTEXT`.
|
||||
#[derive(Clone)]
|
||||
#[repr(C, align(16))]
|
||||
struct HTable {
|
||||
Htable: [u128; HTABLE_LEN],
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct u128 {
|
||||
hi: u64,
|
||||
lo: u64,
|
||||
}
|
||||
|
||||
const HTABLE_LEN: usize = 16;
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Xi(Block);
|
||||
|
||||
impl Xi {
|
||||
#[inline]
|
||||
fn bitxor_assign(&mut self, a: Block) {
|
||||
self.0.bitxor_assign(a)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Xi> for Block {
|
||||
#[inline]
|
||||
fn from(Xi(block): Xi) -> Self {
|
||||
block
|
||||
}
|
||||
}
|
||||
|
||||
// This corresponds roughly to the `GCM128_CONTEXT` structure in BoringSSL.
|
||||
// Some assembly language code, in particular the MOVEBE+AVX2 X86-64
|
||||
// implementation, requires this exact layout.
|
||||
#[repr(C, align(16))]
|
||||
pub(super) struct ContextInner {
|
||||
Xi: Xi,
|
||||
_unused: Block,
|
||||
Htable: HTable,
|
||||
}
|
||||
|
||||
enum Implementation {
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
CLMUL,
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
|
||||
NEON,
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
Fallback,
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn detect_implementation(cpu_features: cpu::Features) -> Implementation {
|
||||
// `cpu_features` is only used for specific platforms.
|
||||
#[cfg(not(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
)))]
|
||||
let _cpu_features = cpu_features;
|
||||
|
||||
#[cfg(any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "x86"
|
||||
))]
|
||||
{
|
||||
if (cpu::intel::FXSR.available(cpu_features)
|
||||
&& cpu::intel::PCLMULQDQ.available(cpu_features))
|
||||
|| cpu::arm::PMULL.available(cpu_features)
|
||||
{
|
||||
return Implementation::CLMUL;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
{
|
||||
if cpu::arm::NEON.available(cpu_features) {
|
||||
return Implementation::NEON;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
return Implementation::NEON;
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
Implementation::Fallback
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn has_avx_movbe(cpu_features: cpu::Features) -> bool {
|
||||
cpu::intel::AVX.available(cpu_features) && cpu::intel::MOVBE.available(cpu_features)
|
||||
}
|
||||
242
zeroidc/vendor/ring/src/aead/gcm/gcm_nohw.rs
vendored
Normal file
242
zeroidc/vendor/ring/src/aead/gcm/gcm_nohw.rs
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
// Copyright (c) 2019, Google Inc.
|
||||
// Portions Copyright 2020 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// This file is based on BoringSSL's gcm_nohw.c.
|
||||
|
||||
// This file contains a constant-time implementation of GHASH based on the notes
|
||||
// in https://bearssl.org/constanttime.html#ghash-for-gcm and the reduction
|
||||
// algorithm described in
|
||||
// https://crypto.stanford.edu/RealWorldCrypto/slides/gueron.pdf.
|
||||
//
|
||||
// Unlike the BearSSL notes, we use u128 in the 64-bit implementation.
|
||||
|
||||
use super::{super::Block, Xi};
|
||||
use crate::endian::BigEndian;
|
||||
use core::convert::TryInto;
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn gcm_mul64_nohw(a: u64, b: u64) -> (u64, u64) {
|
||||
#[inline(always)]
|
||||
fn lo(a: u128) -> u64 {
|
||||
a as u64
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn hi(a: u128) -> u64 {
|
||||
lo(a >> 64)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(a: u64, b: u64) -> u128 {
|
||||
u128::from(a) * u128::from(b)
|
||||
}
|
||||
|
||||
// One term every four bits means the largest term is 64/4 = 16, which barely
|
||||
// overflows into the next term. Using one term every five bits would cost 25
|
||||
// multiplications instead of 16. It is faster to mask off the bottom four
|
||||
// bits of |a|, giving a largest term of 60/4 = 15, and apply the bottom bits
|
||||
// separately.
|
||||
let a0 = a & 0x1111111111111110;
|
||||
let a1 = a & 0x2222222222222220;
|
||||
let a2 = a & 0x4444444444444440;
|
||||
let a3 = a & 0x8888888888888880;
|
||||
|
||||
let b0 = b & 0x1111111111111111;
|
||||
let b1 = b & 0x2222222222222222;
|
||||
let b2 = b & 0x4444444444444444;
|
||||
let b3 = b & 0x8888888888888888;
|
||||
|
||||
let c0 = mul(a0, b0) ^ mul(a1, b3) ^ mul(a2, b2) ^ mul(a3, b1);
|
||||
let c1 = mul(a0, b1) ^ mul(a1, b0) ^ mul(a2, b3) ^ mul(a3, b2);
|
||||
let c2 = mul(a0, b2) ^ mul(a1, b1) ^ mul(a2, b0) ^ mul(a3, b3);
|
||||
let c3 = mul(a0, b3) ^ mul(a1, b2) ^ mul(a2, b1) ^ mul(a3, b0);
|
||||
|
||||
// Multiply the bottom four bits of |a| with |b|.
|
||||
let a0_mask = 0u64.wrapping_sub(a & 1);
|
||||
let a1_mask = 0u64.wrapping_sub((a >> 1) & 1);
|
||||
let a2_mask = 0u64.wrapping_sub((a >> 2) & 1);
|
||||
let a3_mask = 0u64.wrapping_sub((a >> 3) & 1);
|
||||
let extra = u128::from(a0_mask & b)
|
||||
^ (u128::from(a1_mask & b) << 1)
|
||||
^ (u128::from(a2_mask & b) << 2)
|
||||
^ (u128::from(a3_mask & b) << 3);
|
||||
|
||||
let lo = (lo(c0) & 0x1111111111111111)
|
||||
^ (lo(c1) & 0x2222222222222222)
|
||||
^ (lo(c2) & 0x4444444444444444)
|
||||
^ (lo(c3) & 0x8888888888888888)
|
||||
^ lo(extra);
|
||||
let hi = (hi(c0) & 0x1111111111111111)
|
||||
^ (hi(c1) & 0x2222222222222222)
|
||||
^ (hi(c2) & 0x4444444444444444)
|
||||
^ (hi(c3) & 0x8888888888888888)
|
||||
^ hi(extra);
|
||||
(lo, hi)
|
||||
}
|
||||
|
||||
#[cfg(not(target_pointer_width = "64"))]
|
||||
fn gcm_mul32_nohw(a: u32, b: u32) -> u64 {
|
||||
#[inline(always)]
|
||||
fn mul(a: u32, b: u32) -> u64 {
|
||||
u64::from(a) * u64::from(b)
|
||||
}
|
||||
|
||||
// One term every four bits means the largest term is 32/4 = 8, which does not
|
||||
// overflow into the next term.
|
||||
let a0 = a & 0x11111111;
|
||||
let a1 = a & 0x22222222;
|
||||
let a2 = a & 0x44444444;
|
||||
let a3 = a & 0x88888888;
|
||||
|
||||
let b0 = b & 0x11111111;
|
||||
let b1 = b & 0x22222222;
|
||||
let b2 = b & 0x44444444;
|
||||
let b3 = b & 0x88888888;
|
||||
|
||||
let c0 = mul(a0, b0) ^ mul(a1, b3) ^ mul(a2, b2) ^ mul(a3, b1);
|
||||
let c1 = mul(a0, b1) ^ mul(a1, b0) ^ mul(a2, b3) ^ mul(a3, b2);
|
||||
let c2 = mul(a0, b2) ^ mul(a1, b1) ^ mul(a2, b0) ^ mul(a3, b3);
|
||||
let c3 = mul(a0, b3) ^ mul(a1, b2) ^ mul(a2, b1) ^ mul(a3, b0);
|
||||
|
||||
(c0 & 0x1111111111111111)
|
||||
| (c1 & 0x2222222222222222)
|
||||
| (c2 & 0x4444444444444444)
|
||||
| (c3 & 0x8888888888888888)
|
||||
}
|
||||
|
||||
#[cfg(not(target_pointer_width = "64"))]
|
||||
fn gcm_mul64_nohw(a: u64, b: u64) -> (u64, u64) {
|
||||
#[inline(always)]
|
||||
fn lo(a: u64) -> u32 {
|
||||
a as u32
|
||||
}
|
||||
#[inline(always)]
|
||||
fn hi(a: u64) -> u32 {
|
||||
lo(a >> 32)
|
||||
}
|
||||
|
||||
let a0 = lo(a);
|
||||
let a1 = hi(a);
|
||||
let b0 = lo(b);
|
||||
let b1 = hi(b);
|
||||
// Karatsuba multiplication.
|
||||
let lo = gcm_mul32_nohw(a0, b0);
|
||||
let hi = gcm_mul32_nohw(a1, b1);
|
||||
let mid = gcm_mul32_nohw(a0 ^ a1, b0 ^ b1) ^ lo ^ hi;
|
||||
(lo ^ (mid << 32), hi ^ (mid >> 32))
|
||||
}
|
||||
|
||||
pub(super) fn init(xi: [u64; 2]) -> super::u128 {
|
||||
// We implement GHASH in terms of POLYVAL, as described in RFC8452. This
|
||||
// avoids a shift by 1 in the multiplication, needed to account for bit
|
||||
// reversal losing a bit after multiplication, that is,
|
||||
// rev128(X) * rev128(Y) = rev255(X*Y).
|
||||
//
|
||||
// Per Appendix A, we run mulX_POLYVAL. Note this is the same transformation
|
||||
// applied by |gcm_init_clmul|, etc. Note |Xi| has already been byteswapped.
|
||||
//
|
||||
// See also slide 16 of
|
||||
// https://crypto.stanford.edu/RealWorldCrypto/slides/gueron.pdf
|
||||
let mut lo = xi[1];
|
||||
let mut hi = xi[0];
|
||||
|
||||
let mut carry = hi >> 63;
|
||||
carry = 0u64.wrapping_sub(carry);
|
||||
|
||||
hi <<= 1;
|
||||
hi |= lo >> 63;
|
||||
lo <<= 1;
|
||||
|
||||
// The irreducible polynomial is 1 + x^121 + x^126 + x^127 + x^128, so we
|
||||
// conditionally add 0xc200...0001.
|
||||
lo ^= carry & 1;
|
||||
hi ^= carry & 0xc200000000000000;
|
||||
|
||||
// This implementation does not use the rest of |Htable|.
|
||||
super::u128 { lo, hi }
|
||||
}
|
||||
|
||||
fn gcm_polyval_nohw(xi: &mut [u64; 2], h: super::u128) {
|
||||
// Karatsuba multiplication. The product of |Xi| and |H| is stored in |r0|
|
||||
// through |r3|. Note there is no byte or bit reversal because we are
|
||||
// evaluating POLYVAL.
|
||||
let (r0, mut r1) = gcm_mul64_nohw(xi[0], h.lo);
|
||||
let (mut r2, mut r3) = gcm_mul64_nohw(xi[1], h.hi);
|
||||
let (mut mid0, mut mid1) = gcm_mul64_nohw(xi[0] ^ xi[1], h.hi ^ h.lo);
|
||||
mid0 ^= r0 ^ r2;
|
||||
mid1 ^= r1 ^ r3;
|
||||
r2 ^= mid1;
|
||||
r1 ^= mid0;
|
||||
|
||||
// Now we multiply our 256-bit result by x^-128 and reduce. |r2| and
|
||||
// |r3| shifts into position and we must multiply |r0| and |r1| by x^-128. We
|
||||
// have:
|
||||
//
|
||||
// 1 = x^121 + x^126 + x^127 + x^128
|
||||
// x^-128 = x^-7 + x^-2 + x^-1 + 1
|
||||
//
|
||||
// This is the GHASH reduction step, but with bits flowing in reverse.
|
||||
|
||||
// The x^-7, x^-2, and x^-1 terms shift bits past x^0, which would require
|
||||
// another reduction steps. Instead, we gather the excess bits, incorporate
|
||||
// them into |r0| and |r1| and reduce once. See slides 17-19
|
||||
// of https://crypto.stanford.edu/RealWorldCrypto/slides/gueron.pdf.
|
||||
r1 ^= (r0 << 63) ^ (r0 << 62) ^ (r0 << 57);
|
||||
|
||||
// 1
|
||||
r2 ^= r0;
|
||||
r3 ^= r1;
|
||||
|
||||
// x^-1
|
||||
r2 ^= r0 >> 1;
|
||||
r2 ^= r1 << 63;
|
||||
r3 ^= r1 >> 1;
|
||||
|
||||
// x^-2
|
||||
r2 ^= r0 >> 2;
|
||||
r2 ^= r1 << 62;
|
||||
r3 ^= r1 >> 2;
|
||||
|
||||
// x^-7
|
||||
r2 ^= r0 >> 7;
|
||||
r2 ^= r1 << 57;
|
||||
r3 ^= r1 >> 7;
|
||||
|
||||
*xi = [r2, r3];
|
||||
}
|
||||
|
||||
pub(super) fn gmult(xi: &mut Xi, h: super::u128) {
|
||||
with_swapped_xi(xi, |swapped| {
|
||||
gcm_polyval_nohw(swapped, h);
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn ghash(xi: &mut Xi, h: super::u128, input: &[u8]) {
|
||||
with_swapped_xi(xi, |swapped| {
|
||||
input.chunks_exact(16).for_each(|inp| {
|
||||
swapped[0] ^= u64::from_be_bytes(inp[8..].try_into().unwrap());
|
||||
swapped[1] ^= u64::from_be_bytes(inp[..8].try_into().unwrap());
|
||||
gcm_polyval_nohw(swapped, h);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_swapped_xi(Xi(xi): &mut Xi, f: impl FnOnce(&mut [u64; 2])) {
|
||||
let unswapped = xi.u64s_be_to_native();
|
||||
let mut swapped: [u64; 2] = [unswapped[1], unswapped[0]];
|
||||
f(&mut swapped);
|
||||
*xi = Block::from_u64_be(BigEndian::from(swapped[1]), BigEndian::from(swapped[0]))
|
||||
}
|
||||
33
zeroidc/vendor/ring/src/aead/iv.rs
vendored
Normal file
33
zeroidc/vendor/ring/src/aead/iv.rs
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
/// The IV for a single block encryption.
|
||||
///
|
||||
/// Intentionally not `Clone` to ensure each is used only once.
|
||||
#[repr(C)]
|
||||
pub struct Iv([u8; IV_LEN]);
|
||||
|
||||
pub const IV_LEN: usize = 16;
|
||||
|
||||
impl Iv {
|
||||
#[inline]
|
||||
pub fn assume_unique_for_key(a: [u8; IV_LEN]) -> Self {
|
||||
Self(a)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_bytes_less_safe(self) -> [u8; IV_LEN] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
52
zeroidc/vendor/ring/src/aead/nonce.rs
vendored
Normal file
52
zeroidc/vendor/ring/src/aead/nonce.rs
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use crate::error;
|
||||
use core::convert::TryInto;
|
||||
|
||||
/// A nonce for a single AEAD opening or sealing operation.
|
||||
///
|
||||
/// The user must ensure, for a particular key, that each nonce is unique.
|
||||
///
|
||||
/// `Nonce` intentionally doesn't implement `Clone` to ensure that each one is
|
||||
/// consumed at most once.
|
||||
pub struct Nonce([u8; NONCE_LEN]);
|
||||
|
||||
impl Nonce {
|
||||
/// Constructs a `Nonce` with the given value, assuming that the value is
|
||||
/// unique for the lifetime of the key it is being used with.
|
||||
///
|
||||
/// Fails if `value` isn't `NONCE_LEN` bytes long.
|
||||
#[inline]
|
||||
pub fn try_assume_unique_for_key(value: &[u8]) -> Result<Self, error::Unspecified> {
|
||||
let value: &[u8; NONCE_LEN] = value.try_into()?;
|
||||
Ok(Self::assume_unique_for_key(*value))
|
||||
}
|
||||
|
||||
/// Constructs a `Nonce` with the given value, assuming that the value is
|
||||
/// unique for the lifetime of the key it is being used with.
|
||||
#[inline]
|
||||
pub fn assume_unique_for_key(value: [u8; NONCE_LEN]) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8; NONCE_LEN]> for Nonce {
|
||||
fn as_ref(&self) -> &[u8; NONCE_LEN] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// All the AEADs we support use 96-bit nonces.
|
||||
pub const NONCE_LEN: usize = 96 / 8;
|
||||
154
zeroidc/vendor/ring/src/aead/poly1305.rs
vendored
Normal file
154
zeroidc/vendor/ring/src/aead/poly1305.rs
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
// Portions Copyright (c) 2014, 2015, Google Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// TODO: enforce maximum input length.
|
||||
|
||||
use super::{block::BLOCK_LEN, Tag, TAG_LEN};
|
||||
use crate::{c, cpu};
|
||||
|
||||
/// A Poly1305 key.
|
||||
pub(super) struct Key {
|
||||
key_and_nonce: [u8; KEY_LEN],
|
||||
cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
const KEY_LEN: usize = 2 * BLOCK_LEN;
|
||||
|
||||
impl Key {
|
||||
#[inline]
|
||||
pub(super) fn new(key_and_nonce: [u8; KEY_LEN], cpu_features: cpu::Features) -> Self {
|
||||
Self {
|
||||
key_and_nonce,
|
||||
cpu_features,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
state: poly1305_state,
|
||||
#[allow(dead_code)]
|
||||
cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
// Keep in sync with `poly1305_state` in GFp/poly1305.h.
|
||||
//
|
||||
// The C code, in particular the way the `poly1305_aligned_state` functions
|
||||
// are used, is only correct when the state buffer is 64-byte aligned.
|
||||
#[repr(C, align(64))]
|
||||
struct poly1305_state([u8; OPAQUE_LEN]);
|
||||
const OPAQUE_LEN: usize = 512;
|
||||
|
||||
// Abstracts the dispatching logic that chooses the NEON implementation if and
|
||||
// only if it would work.
|
||||
macro_rules! dispatch {
|
||||
( $features:expr =>
|
||||
( $f:ident | $neon_f:ident )
|
||||
( $( $p:ident : $t:ty ),+ )
|
||||
( $( $a:expr ),+ ) ) => {
|
||||
match () {
|
||||
// Apple's 32-bit ARM ABI is incompatible with the assembly code.
|
||||
#[cfg(all(target_arch = "arm", not(target_vendor = "apple")))]
|
||||
() if cpu::arm::NEON.available($features) => {
|
||||
extern "C" {
|
||||
fn $neon_f( $( $p : $t ),+ );
|
||||
}
|
||||
unsafe { $neon_f( $( $a ),+ ) }
|
||||
}
|
||||
() => {
|
||||
extern "C" {
|
||||
fn $f( $( $p : $t ),+ );
|
||||
}
|
||||
unsafe { $f( $( $a ),+ ) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
#[inline]
|
||||
pub(super) fn from_key(
|
||||
Key {
|
||||
key_and_nonce,
|
||||
cpu_features,
|
||||
}: Key,
|
||||
) -> Self {
|
||||
let mut ctx = Self {
|
||||
state: poly1305_state([0u8; OPAQUE_LEN]),
|
||||
cpu_features,
|
||||
};
|
||||
|
||||
dispatch!(
|
||||
cpu_features =>
|
||||
(GFp_poly1305_init | GFp_poly1305_init_neon)
|
||||
(statep: &mut poly1305_state, key: &[u8; KEY_LEN])
|
||||
(&mut ctx.state, &key_and_nonce));
|
||||
|
||||
ctx
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn update(&mut self, input: &[u8]) {
|
||||
dispatch!(
|
||||
self.cpu_features =>
|
||||
(GFp_poly1305_update | GFp_poly1305_update_neon)
|
||||
(statep: &mut poly1305_state, input: *const u8, in_len: c::size_t)
|
||||
(&mut self.state, input.as_ptr(), input.len()));
|
||||
}
|
||||
|
||||
pub(super) fn finish(mut self) -> Tag {
|
||||
let mut tag = Tag([0u8; TAG_LEN]);
|
||||
dispatch!(
|
||||
self.cpu_features =>
|
||||
(GFp_poly1305_finish | GFp_poly1305_finish_neon)
|
||||
(statep: &mut poly1305_state, mac: &mut [u8; TAG_LEN])
|
||||
(&mut self.state, &mut tag.0));
|
||||
tag
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements the original, non-IETF padding semantics.
|
||||
///
|
||||
/// This is used by chacha20_poly1305_openssh and the standalone
|
||||
/// poly1305 test vectors.
|
||||
pub(super) fn sign(key: Key, input: &[u8]) -> Tag {
|
||||
let mut ctx = Context::from_key(key);
|
||||
ctx.update(input);
|
||||
ctx.finish()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test;
|
||||
use core::convert::TryInto;
|
||||
|
||||
// Adapted from BoringSSL's crypto/poly1305/poly1305_test.cc.
|
||||
#[test]
|
||||
pub fn test_poly1305() {
|
||||
let cpu_features = cpu::features();
|
||||
test::run(test_file!("poly1305_test.txt"), |section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
let key = test_case.consume_bytes("Key");
|
||||
let key: &[u8; BLOCK_LEN * 2] = key.as_slice().try_into().unwrap();
|
||||
let input = test_case.consume_bytes("Input");
|
||||
let expected_mac = test_case.consume_bytes("MAC");
|
||||
let key = Key::new(*key, cpu_features);
|
||||
let Tag(actual_mac) = sign(key, &input);
|
||||
assert_eq!(expected_mac, actual_mac.as_ref());
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
170
zeroidc/vendor/ring/src/aead/poly1305_test.txt
vendored
Normal file
170
zeroidc/vendor/ring/src/aead/poly1305_test.txt
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
# Test Vectors from OpenSSL commit bbe9769ba66ab2512678a87b0d9b266ba970db05.
|
||||
|
||||
Key = 2d773be37adb1e4d683bf0075e79c4ee037918535a7f99ccb7040fb5f5f43aea
|
||||
Input = 89dab80b7717c1db5db437860a3f70218e93e1b8f461fb677f16f35f6f87e2a91c99bc3a47ace47640cc95c345be5ecca5a3523c35cc01893af0b64a620334270372ec12482d1b1e363561698a578b359803495bb4e2ef1930b17a5190b580f141300df30adbeca28f6427a8bc1a999fd51c554a017d095d8c3e3127daf9f595
|
||||
MAC = c85d15ed44c378d6b00e23064c7bcd51
|
||||
|
||||
Key = 99e5822dd4173c995e3dae0ddefb97743fde3b080134b39f76e9bf8d0e88d546
|
||||
Input = 000000000000000b170303020000000006db1f1f368d696a810a349c0c714c9a5e7850c2407d721acded95e018d7a85266a6e1289cdb4aeb18da5ac8a2b0026d24a59ad485227f3eaedbb2e7e35e1c66cd60f9abf716dcc9ac42682dd7dab287a7024c4eefc321cc0574e16793e37cec03c5bda42b54c114a80b57af26416c7be742005e20855c73e21dc8e2edc9d435cb6f6059280011c270b71570051c1c9b3052126620bc1e2730fa066c7a509d53c60e5ae1b40aa6e39e49669228c90eecb4a50db32a50bc49e90b4f4b359a1dfd11749cd3867fcf2fb7bb6cd4738f6a4ad6f7ca5058f7618845af9f020f6c3b967b8f4cd4a91e2813b507ae66f2d35c18284f7292186062e10fd5510d18775351ef334e7634ab4743f5b68f49adcab384d3fd75f7390f4006ef2a295c8c7a076ad54546cd25d2107fbe1436c840924aaebe5b370893cd63d1325b8616fc4810886bc152c53221b6df373119393255ee72bcaa880174f1717f9184fa91646f17a24ac55d16bfddca9581a92eda479201f0edbf633600d6066d1ab36d5d2415d71351bbcd608a25108d25641992c1f26c531cf9f90203bc4cc19f5927d834b0a47116d3884bbb164b8ec883d1ac832e56b3918a98601a08d171881541d594db399c6ae6151221745aec814c45b0b05b565436fd6f137aa10a0c0b643761dbd6f9a9dcb99b1a6e690854ce0769cde39761d82fcdec15f0d92d7d8e94ade8eb83fbe0
|
||||
MAC = 2637408fe13086ea73f971e3425e2820
|
||||
|
||||
|
||||
# RFC 7539, section 2.5.2.
|
||||
|
||||
Key = 85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b
|
||||
Input = "Cryptographic Forum Research Group"
|
||||
MAC = a8061dc1305136c6c22b8baf0c0127a9
|
||||
|
||||
|
||||
# RFC 7539, section A.3.
|
||||
|
||||
Key = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
Input = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
MAC = 00000000000000000000000000000000
|
||||
|
||||
Key = 0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e
|
||||
Input = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f
|
||||
MAC = 36e5f6b5c5e06070f0efca96227a863e
|
||||
|
||||
Key = 36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000
|
||||
Input = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f
|
||||
MAC = f3477e7cd95417af89a6b8794c310cf0
|
||||
|
||||
Key = 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0
|
||||
Input = 2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e
|
||||
MAC = 4541669a7eaaee61e708dc7cbcc5eb62
|
||||
|
||||
Key = 0200000000000000000000000000000000000000000000000000000000000000
|
||||
Input = ffffffffffffffffffffffffffffffff
|
||||
MAC = 03000000000000000000000000000000
|
||||
|
||||
Key = 02000000000000000000000000000000ffffffffffffffffffffffffffffffff
|
||||
Input = 02000000000000000000000000000000
|
||||
MAC = 03000000000000000000000000000000
|
||||
|
||||
Key = 0100000000000000000000000000000000000000000000000000000000000000
|
||||
Input = fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff11000000000000000000000000000000
|
||||
MAC = 05000000000000000000000000000000
|
||||
|
||||
Key = 0100000000000000000000000000000000000000000000000000000000000000
|
||||
Input = fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe01010101010101010101010101010101
|
||||
MAC = 00000000000000000000000000000000
|
||||
|
||||
Key = 0200000000000000000000000000000000000000000000000000000000000000
|
||||
Input = fdffffffffffffffffffffffffffffff
|
||||
MAC = faffffffffffffffffffffffffffffff
|
||||
|
||||
Key = 0100000000000000040000000000000000000000000000000000000000000000
|
||||
Input = e33594d7505e43b900000000000000003394d7505e4379cd01000000000000000000000000000000000000000000000001000000000000000000000000000000
|
||||
MAC = 14000000000000005500000000000000
|
||||
|
||||
Key = 0100000000000000040000000000000000000000000000000000000000000000
|
||||
Input = e33594d7505e43b900000000000000003394d7505e4379cd010000000000000000000000000000000000000000000000
|
||||
MAC = 13000000000000000000000000000000
|
||||
|
||||
|
||||
# Additional test vectors that are long enough to ensure OpenSSL's SIMD
|
||||
# assembly is fully tested.
|
||||
|
||||
# Length 2048.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfed
|
||||
MAC = 69d28f73dd09d39a92aa179da354b7ea
|
||||
|
||||
# Length 2049.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc8
|
||||
MAC = d6a26654b88572e875d9661c83471c1b
|
||||
|
||||
# Length 2050.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852
|
||||
MAC = 9fbbb7f7adcd0cd5b46a4a520b22499a
|
||||
|
||||
# Length 2051.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f5
|
||||
MAC = eb7cdceb97ade2a07622f8f5a4b1ce15
|
||||
|
||||
# Length 2052.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f590
|
||||
MAC = d41c310927cd92e14784ea78b85503db
|
||||
|
||||
# Length 2053.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073
|
||||
MAC = 16af133c423f783a14c49d9f526384cf
|
||||
|
||||
# Length 2054.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4
|
||||
MAC = 00c75db8f0636b22f195645b03091f5f
|
||||
|
||||
# Length 2055.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f434
|
||||
MAC = 4a532bc740f581555831345f3b75bf33
|
||||
|
||||
# Length 2056.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a
|
||||
MAC = 698c7d32c5923871d124a2479e521706
|
||||
|
||||
# Length 2057.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c
|
||||
MAC = a677187dbf3c927aeeafb9ebce0f61dc
|
||||
|
||||
# Length 2058.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a
|
||||
MAC = 201fed7eee981b31d2cc42ff6c38141a
|
||||
|
||||
# Length 2059.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28
|
||||
MAC = 0c3d3d01a37f347c4f7c5826bcafb3e1
|
||||
|
||||
# Length 2060.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c9
|
||||
MAC = 33a4e0e0bed7c84c5cc5dd4784410f07
|
||||
|
||||
# Length 2061.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e
|
||||
MAC = 8e41c40a2f8ec58fe594f3a3a2de4ae1
|
||||
|
||||
# Length 2062.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e21
|
||||
MAC = c6e5d1810fd878ac6b844c66cef36a22
|
||||
|
||||
# Length 2063.
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
Input = 248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e874cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936aff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a3709894e4eb0a4eedc4ae19468e66b81f271351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb14cf77bde35e78ae9ad7d3f57ed7e7f23926c9172f82d77684ea5ed7d74ebc6f142b997036bcb7cce8df1bbc0d5b35a46509c954fc9469d214d6238f166cbf872156b4c41d7aac5942cffb175023078252a3f36e315c5d4ce0e39928a018252862becacef96a19f03bdcf46d75584299d1f8b03c0169e9e407d937145b5e5024139e7022a1978f114f24cdfa23780a119735c41da8fb759bbb3f025c6ec30e6c6e9bce8615be68e392fce59fd26a8e6a6cc5c606e3848116e4d01d29565a1facfb524b6d29643b826eee1e42869fc76df229dd79b39a2b1df28bb335c3a5f15a855d0121e4a6da34b5e4d5b7b5d5746a03ecff70811e1516fcec1bf7462e8876a2d21710aa168c78f45a6a15015950e221da85d3ec822ad6d0a6931b25a06b7bb5f3c10bb36cd4d647f9561982fde9818de5d4bf8db7f86c53b4ff14928ac15f79023b61861e73e44216540bb302153770da2533de9795252ab5fb77ad924c9338c8144c23d4c90dab9a18feac1a1574d4545e1435eb405e6c4c439fc724fce992ae85badf345bad16d85fbd338f04433703614754d0e7e54c4ccde2670587d52ecfb5a70a14a501bacc727722649931d8515b13d020a78e511fe136d45fbf97f9c7f689fcc677cfb3683723878350ffe9d08130cc6e567b6179e01b7eb2b3bbcf0873e1308eec018edeb8cce946338e15d5bf68c71916a83a99358039ef071e009546a2df936879dffbba397a93925d229a469fd17d71b7f524e03a30da6ee927542f8b369bed4734fe25dbd63d24ffd2a222f5f84f75d858ab989be925af570ad6d45bd28ce61b5139e1dd2f0b7795fe072e6e83acbb5e7b777a70c641e4cab2af40eed69abc334cd2703c3273204fac580c6a3d6680427e5f7d051e8380a53f93a180f4556ecea4530b9a2d5948dad63d415b6874f6b90e767d6d265be86351b53ba690780bb57c21b57418c5b97559e840c68257f839e7583a4bf7c7645c5987d40cc1ba79a218c35edfacdabe581d950e4bb7a481ebe64d61d00e75b1f25f1ce5f5462334a5b9038a697aa0937a3f8017e05d2c9c05dcb05c0b02508dea619b137f5444b6f088eb3cb2c66788f88afdfbba8faa1c490485624c88ae11e57347a676902e7553f056188493209bdbb30acc63c9e41e16a9d6c009416b520a76ba38f57628170c43626b5cb46179dc5bf65de865085f84bf741c223fbe474d2d19d8f43914fbd6586351089e73babf344f988b7963fe44528457d7aad3c564f6bcbd0d772a4c9fd328e6022d1c7c9f86726f8d5a23797d309c0f653ab1ac687833eb2700f156296062a8b377078f45f6b68c3d07cae1913ba8d5a6f9bf7525a3439eb932d4cefc4bf8e1b07b48ca13ece366cbc3e0388915915d1757475103a9e9454e7e6355de2d6acbf4710f9a63e4f6d3cd70c2d6fca88dd8a14448fdb63ce9350fdaafbe0b8bd1c5d307dae76dfed799aef2d8f23d5608d37d1330dd38b94860905dbeebf78d7b7318b7d42aed40d3f9899e9f420cbd92a6eeae3026f7725694e0e4bee016ba346fed2c21172bdb4a461cebe0cfe38e76645226ac127a259c193264d735ce8c8a57e17dd3f0579e2e86dc295ad1f45ba2d85db35044da61f7d401274b31eefbeb34e8d2ae596e9b4541aae117bdac5ed0b324c20539c27c07a411d5288b0b5f6fa16e9a7df85dc319fa6b71cd08a859c06a3f7b0289e1750adbf182f9750fea96fea5ab7aa3473340607cd7ed2c626f5382491c26d5d5bea61401dee7319c94d418f297e61ceac8f258ee8c23831bda081591f5a918e96855774ddedffc51e5b180f1971806d42fc333020b734aeb45adb0bc47325d0cea5f6713a786558022afc39d573892aa3635efbfd8bcb11c57f306c72146afe8b45388125cb7bf9ecf965a7ba4f768c77be366470dcdcf214b7f6a5a9460ed4fe44ae559d85e2fdc2094de83fff12ea8804db1215c4ca865871bdd7f8ef32ab799bf923ffb02c1ded7d129beadad46c5eda31ab1a6f43da05ea08bff7ffa88d8966353d01830558c39b930b01d175e437124d8edd0d2698fd8932f2b2c9b14746e52879c57a395538150f390264f00e60d470711202f4194499ff79037ca9885dc8d695f7d917a3086ca88e8f8d0243efee09302cf39e039eb7cc8dd19d28120d5fe533b5727cd39133181c729ca6f90a015ed30be7668d5cb5ecc33a53ee69bf7d1a5ecbdb153803743c6adaaabd36bf84e5be38d3f04a5d5dbfd67bdcd3b176e65bd1391ade775cc32ce43a847fb6c672a3fe97a5d4081c4986959ec5fb898f42a9397ba2b3ec2c1018f8d76d057f2366bd0e4465514ad6560c599664fb85621fe771e00f43d39b591b2a6a321100f4d1ef23a376d5ae3eeedbfe23da73dff0ee4d16b34ebddd8f5f053db9824105fc7300dbee7ea6af56b112319e3e215a0fc79ae946f6b5227453ec7fcaf17cf7651f71499a50d81221404d5f129ac50ea7528ff0e0069ec4ab8acb7919d81749ab37a870c5ef2cc5a15cf96709d3c65b4addc77e7416847160bcabb94ea36377e0ef71be80b5cc53effd5444888044a353574c72c924bba2a8b4e8354188ebfedc852f59073f4347a8c8a28c99e21df
|
||||
MAC = f6eaae369c3cb5c05748e8d919178e00
|
||||
|
||||
# Regression test for https://rt.openssl.org/Ticket/Display.html?id=4439
|
||||
Key = 2d773be37adb1e4d683bf0075e79c4ee037918535a7f99ccb7040fb5f5f43aea
|
||||
Input = 89dab80b7717c1db5db437860a3f70218e93e1b8f461fb677f16f35f6f87e2a91c99bc3a47ace47640cc95c345be5ecca5a3523c35cc01893af0b64a620334270372ec12482d1b1e363561698a578b359803495bb4e2ef1930b17a5190b580f141300df30adbeca28f6427a8bc1a999fd51c554a017d095d8c3e3127daf9f595
|
||||
MAC = c85d15ed44c378d6b00e23064c7bcd51
|
||||
|
||||
# Regression tests for https://rt.openssl.org/Ticket/Display.html?id=4483
|
||||
|
||||
Key = 7f1b02640000000000000000000000000000000000000000cccccccccccccccc
|
||||
Input = cccccccccccccccccccccccccccccccccccccccccccccccccc80ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccceccccccccccccccccccccccccccccccccccccc5cccccccccccccccccccccccccccccccccccccccccce3ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaccccccccccccccccccccce6cccccccccc000000afccccccccccccccccccfffffff5000000000000000000000000000000000000000000000000000000ffffffe70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000719205a8521dfc
|
||||
MAC = 8559b876eceed66eb37798c0457baff9
|
||||
|
||||
Key = e00016000000000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
Input = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000800264
|
||||
MAC = 00bd1258978e205444c9aaaa82006fed
|
||||
|
||||
Key = 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
|
||||
Input = 02fc
|
||||
MAC = 06120c0c0c0c0c0c0c0c0c0c0c0c0c0c
|
||||
|
||||
Key = 00ff000000000000000000000000000000000000001e00000000000000007b7b
|
||||
Input = 7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b007b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b001300000000b300000000000000000000000000000000000000000000f20000000000000000000000000000000000002000efff0009000000000000000000000000100000000009000000640000000000000000000000001300000000b300000000000000000000000000000000000000000000f20000000000000000000000000000000000002000efff00090000000000000000007a000010000000000900000064000000000000000000000000000000000000000000000000fc
|
||||
MAC = 33205bbf9e9f8f7212ab9e2ab9b7e4a5
|
||||
186
zeroidc/vendor/ring/src/aead/quic.rs
vendored
Normal file
186
zeroidc/vendor/ring/src/aead/quic.rs
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! QUIC Header Protection.
|
||||
//!
|
||||
//! See draft-ietf-quic-tls.
|
||||
|
||||
use crate::{
|
||||
aead::{aes, chacha},
|
||||
cpu, error, hkdf,
|
||||
};
|
||||
use core::convert::{TryFrom, TryInto};
|
||||
|
||||
/// A key for generating QUIC Header Protection masks.
|
||||
pub struct HeaderProtectionKey {
|
||||
inner: KeyInner,
|
||||
algorithm: &'static Algorithm,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant, variant_size_differences)]
|
||||
enum KeyInner {
|
||||
Aes(aes::Key),
|
||||
ChaCha20(chacha::Key),
|
||||
}
|
||||
|
||||
impl From<hkdf::Okm<'_, &'static Algorithm>> for HeaderProtectionKey {
|
||||
fn from(okm: hkdf::Okm<&'static Algorithm>) -> Self {
|
||||
let mut key_bytes = [0; super::MAX_KEY_LEN];
|
||||
let algorithm = *okm.len();
|
||||
let key_bytes = &mut key_bytes[..algorithm.key_len()];
|
||||
okm.fill(key_bytes).unwrap();
|
||||
Self::new(algorithm, key_bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl HeaderProtectionKey {
|
||||
/// Create a new header protection key.
|
||||
///
|
||||
/// `key_bytes` must be exactly `algorithm.key_len` bytes long.
|
||||
pub fn new(
|
||||
algorithm: &'static Algorithm,
|
||||
key_bytes: &[u8],
|
||||
) -> Result<Self, error::Unspecified> {
|
||||
Ok(Self {
|
||||
inner: (algorithm.init)(key_bytes, cpu::features())?,
|
||||
algorithm,
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate a new QUIC Header Protection mask.
|
||||
///
|
||||
/// `sample` must be exactly `self.algorithm().sample_len()` bytes long.
|
||||
pub fn new_mask(&self, sample: &[u8]) -> Result<[u8; 5], error::Unspecified> {
|
||||
let sample = <&[u8; SAMPLE_LEN]>::try_from(sample)?;
|
||||
|
||||
let out = (self.algorithm.new_mask)(&self.inner, *sample);
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// The key's algorithm.
|
||||
#[inline(always)]
|
||||
pub fn algorithm(&self) -> &'static Algorithm {
|
||||
self.algorithm
|
||||
}
|
||||
}
|
||||
|
||||
const SAMPLE_LEN: usize = super::TAG_LEN;
|
||||
|
||||
/// QUIC sample for new key masks
|
||||
pub type Sample = [u8; SAMPLE_LEN];
|
||||
|
||||
/// A QUIC Header Protection Algorithm.
|
||||
pub struct Algorithm {
|
||||
init: fn(key: &[u8], cpu_features: cpu::Features) -> Result<KeyInner, error::Unspecified>,
|
||||
|
||||
new_mask: fn(key: &KeyInner, sample: Sample) -> [u8; 5],
|
||||
|
||||
key_len: usize,
|
||||
id: AlgorithmID,
|
||||
}
|
||||
|
||||
impl hkdf::KeyType for &'static Algorithm {
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
self.key_len()
|
||||
}
|
||||
}
|
||||
|
||||
impl Algorithm {
|
||||
/// The length of the key.
|
||||
#[inline(always)]
|
||||
pub fn key_len(&self) -> usize {
|
||||
self.key_len
|
||||
}
|
||||
|
||||
/// The required sample length.
|
||||
#[inline(always)]
|
||||
pub fn sample_len(&self) -> usize {
|
||||
SAMPLE_LEN
|
||||
}
|
||||
}
|
||||
|
||||
derive_debug_via_id!(Algorithm);
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum AlgorithmID {
|
||||
AES_128,
|
||||
AES_256,
|
||||
CHACHA20,
|
||||
}
|
||||
|
||||
impl PartialEq for Algorithm {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Algorithm {}
|
||||
|
||||
/// AES-128.
|
||||
pub static AES_128: Algorithm = Algorithm {
|
||||
key_len: 16,
|
||||
init: aes_init_128,
|
||||
new_mask: aes_new_mask,
|
||||
id: AlgorithmID::AES_128,
|
||||
};
|
||||
|
||||
/// AES-256.
|
||||
pub static AES_256: Algorithm = Algorithm {
|
||||
key_len: 32,
|
||||
init: aes_init_256,
|
||||
new_mask: aes_new_mask,
|
||||
id: AlgorithmID::AES_256,
|
||||
};
|
||||
|
||||
fn aes_init_128(key: &[u8], cpu_features: cpu::Features) -> Result<KeyInner, error::Unspecified> {
|
||||
let aes_key = aes::Key::new(key, aes::Variant::AES_128, cpu_features)?;
|
||||
Ok(KeyInner::Aes(aes_key))
|
||||
}
|
||||
|
||||
fn aes_init_256(key: &[u8], cpu_features: cpu::Features) -> Result<KeyInner, error::Unspecified> {
|
||||
let aes_key = aes::Key::new(key, aes::Variant::AES_256, cpu_features)?;
|
||||
Ok(KeyInner::Aes(aes_key))
|
||||
}
|
||||
|
||||
fn aes_new_mask(key: &KeyInner, sample: Sample) -> [u8; 5] {
|
||||
let aes_key = match key {
|
||||
KeyInner::Aes(key) => key,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
aes_key.new_mask(sample)
|
||||
}
|
||||
|
||||
/// ChaCha20.
|
||||
pub static CHACHA20: Algorithm = Algorithm {
|
||||
key_len: chacha::KEY_LEN,
|
||||
init: chacha20_init,
|
||||
new_mask: chacha20_new_mask,
|
||||
id: AlgorithmID::CHACHA20,
|
||||
};
|
||||
|
||||
fn chacha20_init(key: &[u8], _todo: cpu::Features) -> Result<KeyInner, error::Unspecified> {
|
||||
let chacha20_key: [u8; chacha::KEY_LEN] = key.try_into()?;
|
||||
Ok(KeyInner::ChaCha20(chacha::Key::from(chacha20_key)))
|
||||
}
|
||||
|
||||
fn chacha20_new_mask(key: &KeyInner, sample: Sample) -> [u8; 5] {
|
||||
let chacha20_key = match key {
|
||||
KeyInner::ChaCha20(key) => key,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
chacha20_key.new_mask(sample)
|
||||
}
|
||||
51
zeroidc/vendor/ring/src/aead/shift.rs
vendored
Normal file
51
zeroidc/vendor/ring/src/aead/shift.rs
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::block::{Block, BLOCK_LEN};
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub fn shift_full_blocks<F>(in_out: &mut [u8], in_prefix_len: usize, mut transform: F)
|
||||
where
|
||||
F: FnMut(&[u8; BLOCK_LEN]) -> Block,
|
||||
{
|
||||
use core::convert::TryFrom;
|
||||
|
||||
let in_out_len = in_out.len().checked_sub(in_prefix_len).unwrap();
|
||||
|
||||
for i in (0..in_out_len).step_by(BLOCK_LEN) {
|
||||
let block = {
|
||||
let input =
|
||||
<&[u8; BLOCK_LEN]>::try_from(&in_out[(in_prefix_len + i)..][..BLOCK_LEN]).unwrap();
|
||||
transform(input)
|
||||
};
|
||||
let output = <&mut [u8; BLOCK_LEN]>::try_from(&mut in_out[i..][..BLOCK_LEN]).unwrap();
|
||||
*output = *block.as_ref();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shift_partial<F>((in_prefix_len, in_out): (usize, &mut [u8]), transform: F)
|
||||
where
|
||||
F: FnOnce(&[u8]) -> Block,
|
||||
{
|
||||
let (block, in_out_len) = {
|
||||
let input = &in_out[in_prefix_len..];
|
||||
let in_out_len = input.len();
|
||||
if in_out_len == 0 {
|
||||
return;
|
||||
}
|
||||
debug_assert!(in_out_len < BLOCK_LEN);
|
||||
(transform(input), in_out_len)
|
||||
};
|
||||
in_out[..in_out_len].copy_from_slice(&block.as_ref()[..in_out_len]);
|
||||
}
|
||||
320
zeroidc/vendor/ring/src/agreement.rs
vendored
Normal file
320
zeroidc/vendor/ring/src/agreement.rs
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
// Copyright 2015-2017 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Key Agreement: ECDH, including X25519.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! Note that this example uses X25519, but ECDH using NIST P-256/P-384 is done
|
||||
//! exactly the same way, just substituting
|
||||
//! `agreement::ECDH_P256`/`agreement::ECDH_P384` for `agreement::X25519`.
|
||||
//!
|
||||
//! ```
|
||||
//! use ring::{agreement, rand};
|
||||
//!
|
||||
//! let rng = rand::SystemRandom::new();
|
||||
//!
|
||||
//! let my_private_key = agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng)?;
|
||||
//!
|
||||
//! // Make `my_public_key` a byte slice containing my public key. In a real
|
||||
//! // application, this would be sent to the peer in an encoded protocol
|
||||
//! // message.
|
||||
//! let my_public_key = my_private_key.compute_public_key()?;
|
||||
//!
|
||||
//! let peer_public_key = {
|
||||
//! // In a real application, the peer public key would be parsed out of a
|
||||
//! // protocol message. Here we just generate one.
|
||||
//! let peer_public_key = {
|
||||
//! let peer_private_key =
|
||||
//! agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng)?;
|
||||
//! peer_private_key.compute_public_key()?
|
||||
//! };
|
||||
//!
|
||||
//! agreement::UnparsedPublicKey::new(&agreement::X25519, peer_public_key)
|
||||
//! };
|
||||
//!
|
||||
//! agreement::agree_ephemeral(
|
||||
//! my_private_key,
|
||||
//! &peer_public_key,
|
||||
//! ring::error::Unspecified,
|
||||
//! |_key_material| {
|
||||
//! // In a real application, we'd apply a KDF to the key material and the
|
||||
//! // public keys (as recommended in RFC 7748) and then derive session
|
||||
//! // keys from the result. We omit all that here.
|
||||
//! Ok(())
|
||||
//! },
|
||||
//! )?;
|
||||
//!
|
||||
//! # Ok::<(), ring::error::Unspecified>(())
|
||||
//! ```
|
||||
|
||||
// The "NSA Guide" steps here are from from section 3.1, "Ephemeral Unified
|
||||
// Model."
|
||||
|
||||
use crate::{cpu, debug, ec, error, rand};
|
||||
|
||||
pub use crate::ec::{
|
||||
curve25519::x25519::X25519,
|
||||
suite_b::ecdh::{ECDH_P256, ECDH_P384},
|
||||
};
|
||||
|
||||
/// A key agreement algorithm.
|
||||
pub struct Algorithm {
|
||||
pub(crate) curve: &'static ec::Curve,
|
||||
pub(crate) ecdh: fn(
|
||||
out: &mut [u8],
|
||||
private_key: &ec::Seed,
|
||||
peer_public_key: untrusted::Input,
|
||||
) -> Result<(), error::Unspecified>,
|
||||
}
|
||||
|
||||
derive_debug_via_field!(Algorithm, curve);
|
||||
|
||||
impl Eq for Algorithm {}
|
||||
impl PartialEq for Algorithm {
|
||||
fn eq(&self, other: &Algorithm) -> bool {
|
||||
self.curve.id == other.curve.id
|
||||
}
|
||||
}
|
||||
|
||||
/// An ephemeral private key for use (only) with `agree_ephemeral`. The
|
||||
/// signature of `agree_ephemeral` ensures that an `EphemeralPrivateKey` can be
|
||||
/// used for at most one key agreement.
|
||||
pub struct EphemeralPrivateKey {
|
||||
private_key: ec::Seed,
|
||||
algorithm: &'static Algorithm,
|
||||
}
|
||||
|
||||
derive_debug_via_field!(
|
||||
EphemeralPrivateKey,
|
||||
stringify!(EphemeralPrivateKey),
|
||||
algorithm
|
||||
);
|
||||
|
||||
impl EphemeralPrivateKey {
|
||||
/// Generate a new ephemeral private key for the given algorithm.
|
||||
pub fn generate(
|
||||
alg: &'static Algorithm,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
) -> Result<Self, error::Unspecified> {
|
||||
let cpu_features = cpu::features();
|
||||
|
||||
// NSA Guide Step 1.
|
||||
//
|
||||
// This only handles the key generation part of step 1. The rest of
|
||||
// step one is done by `compute_public_key()`.
|
||||
let private_key = ec::Seed::generate(&alg.curve, rng, cpu_features)?;
|
||||
Ok(Self {
|
||||
private_key,
|
||||
algorithm: alg,
|
||||
})
|
||||
}
|
||||
|
||||
/// Computes the public key from the private key.
|
||||
#[inline(always)]
|
||||
pub fn compute_public_key(&self) -> Result<PublicKey, error::Unspecified> {
|
||||
// NSA Guide Step 1.
|
||||
//
|
||||
// Obviously, this only handles the part of Step 1 between the private
|
||||
// key generation and the sending of the public key to the peer. `out`
|
||||
// is what should be sent to the peer.
|
||||
self.private_key
|
||||
.compute_public_key()
|
||||
.map(|public_key| PublicKey {
|
||||
algorithm: self.algorithm,
|
||||
bytes: public_key,
|
||||
})
|
||||
}
|
||||
|
||||
/// The algorithm for the private key.
|
||||
#[inline]
|
||||
pub fn algorithm(&self) -> &'static Algorithm {
|
||||
self.algorithm
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn bytes(&self) -> &[u8] {
|
||||
self.private_key.bytes_less_safe()
|
||||
}
|
||||
}
|
||||
|
||||
/// A public key for key agreement.
|
||||
#[derive(Clone)]
|
||||
pub struct PublicKey {
|
||||
algorithm: &'static Algorithm,
|
||||
bytes: ec::PublicKey,
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for PublicKey {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.bytes.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for PublicKey {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
f.debug_struct("PublicKey")
|
||||
.field("algorithm", &self.algorithm)
|
||||
.field("bytes", &debug::HexStr(self.as_ref()))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl PublicKey {
|
||||
/// The algorithm for the public key.
|
||||
#[inline]
|
||||
pub fn algorithm(&self) -> &'static Algorithm {
|
||||
self.algorithm
|
||||
}
|
||||
}
|
||||
|
||||
/// An unparsed, possibly malformed, public key for key agreement.
|
||||
pub struct UnparsedPublicKey<B: AsRef<[u8]>> {
|
||||
algorithm: &'static Algorithm,
|
||||
bytes: B,
|
||||
}
|
||||
|
||||
impl<B: Copy> Copy for UnparsedPublicKey<B> where B: AsRef<[u8]> {}
|
||||
|
||||
impl<B: Clone> Clone for UnparsedPublicKey<B>
|
||||
where
|
||||
B: AsRef<[u8]>,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
algorithm: self.algorithm,
|
||||
bytes: self.bytes.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: core::fmt::Debug> core::fmt::Debug for UnparsedPublicKey<B>
|
||||
where
|
||||
B: AsRef<[u8]>,
|
||||
{
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
f.debug_struct("UnparsedPublicKey")
|
||||
.field("algorithm", &self.algorithm)
|
||||
.field("bytes", &debug::HexStr(self.bytes.as_ref()))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
|
||||
/// Constructs a new `UnparsedPublicKey`.
|
||||
pub fn new(algorithm: &'static Algorithm, bytes: B) -> Self {
|
||||
Self { algorithm, bytes }
|
||||
}
|
||||
|
||||
/// TODO: doc
|
||||
#[inline]
|
||||
pub fn algorithm(&self) -> &'static Algorithm {
|
||||
self.algorithm
|
||||
}
|
||||
|
||||
/// TODO: doc
|
||||
#[inline]
|
||||
pub fn bytes(&self) -> &B {
|
||||
&self.bytes
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs a key agreement with an ephemeral private key and the given public
|
||||
/// key.
|
||||
///
|
||||
/// `my_private_key` is the ephemeral private key to use. Since it is moved, it
|
||||
/// will not be usable after calling `agree_ephemeral`, thus guaranteeing that
|
||||
/// the key is used for only one key agreement.
|
||||
///
|
||||
/// `peer_public_key` is the peer's public key. `agree_ephemeral` will return
|
||||
/// `Err(error_value)` if it does not match `my_private_key's` algorithm/curve.
|
||||
/// `agree_ephemeral` verifies that it is encoded in the standard form for the
|
||||
/// algorithm and that the key is *valid*; see the algorithm's documentation for
|
||||
/// details on how keys are to be encoded and what constitutes a valid key for
|
||||
/// that algorithm.
|
||||
///
|
||||
/// `error_value` is the value to return if an error occurs before `kdf` is
|
||||
/// called, e.g. when decoding of the peer's public key fails or when the public
|
||||
/// key is otherwise invalid.
|
||||
///
|
||||
/// After the key agreement is done, `agree_ephemeral` calls `kdf` with the raw
|
||||
/// key material from the key agreement operation and then returns what `kdf`
|
||||
/// returns.
|
||||
#[inline]
|
||||
pub fn agree_ephemeral<B: AsRef<[u8]>, F, R, E>(
|
||||
my_private_key: EphemeralPrivateKey,
|
||||
peer_public_key: &UnparsedPublicKey<B>,
|
||||
error_value: E,
|
||||
kdf: F,
|
||||
) -> Result<R, E>
|
||||
where
|
||||
F: FnOnce(&[u8]) -> Result<R, E>,
|
||||
{
|
||||
let peer_public_key = UnparsedPublicKey {
|
||||
algorithm: peer_public_key.algorithm,
|
||||
bytes: peer_public_key.bytes.as_ref(),
|
||||
};
|
||||
agree_ephemeral_(my_private_key, peer_public_key, error_value, kdf)
|
||||
}
|
||||
|
||||
fn agree_ephemeral_<F, R, E>(
|
||||
my_private_key: EphemeralPrivateKey,
|
||||
peer_public_key: UnparsedPublicKey<&[u8]>,
|
||||
error_value: E,
|
||||
kdf: F,
|
||||
) -> Result<R, E>
|
||||
where
|
||||
F: FnOnce(&[u8]) -> Result<R, E>,
|
||||
{
|
||||
// NSA Guide Prerequisite 1.
|
||||
//
|
||||
// The domain parameters are hard-coded. This check verifies that the
|
||||
// peer's public key's domain parameters match the domain parameters of
|
||||
// this private key.
|
||||
if peer_public_key.algorithm != my_private_key.algorithm {
|
||||
return Err(error_value);
|
||||
}
|
||||
|
||||
let alg = &my_private_key.algorithm;
|
||||
|
||||
// NSA Guide Prerequisite 2, regarding which KDFs are allowed, is delegated
|
||||
// to the caller.
|
||||
|
||||
// NSA Guide Prerequisite 3, "Prior to or during the key-agreement process,
|
||||
// each party shall obtain the identifier associated with the other party
|
||||
// during the key-agreement scheme," is delegated to the caller.
|
||||
|
||||
// NSA Guide Step 1 is handled by `EphemeralPrivateKey::generate()` and
|
||||
// `EphemeralPrivateKey::compute_public_key()`.
|
||||
|
||||
let mut shared_key = [0u8; ec::ELEM_MAX_BYTES];
|
||||
let shared_key = &mut shared_key[..alg.curve.elem_scalar_seed_len];
|
||||
|
||||
// NSA Guide Steps 2, 3, and 4.
|
||||
//
|
||||
// We have a pretty liberal interpretation of the NIST's spec's "Destroy"
|
||||
// that doesn't meet the NSA requirement to "zeroize."
|
||||
(alg.ecdh)(
|
||||
shared_key,
|
||||
&my_private_key.private_key,
|
||||
untrusted::Input::from(peer_public_key.bytes),
|
||||
)
|
||||
.map_err(|_| error_value)?;
|
||||
|
||||
// NSA Guide Steps 5 and 6.
|
||||
//
|
||||
// Again, we have a pretty liberal interpretation of the NIST's spec's
|
||||
// "Destroy" that doesn't meet the NSA requirement to "zeroize."
|
||||
kdf(shared_key)
|
||||
}
|
||||
21
zeroidc/vendor/ring/src/arithmetic.rs
vendored
Normal file
21
zeroidc/vendor/ring/src/arithmetic.rs
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2017 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#[macro_use]
|
||||
pub mod constant;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod bigint;
|
||||
|
||||
pub mod montgomery;
|
||||
1627
zeroidc/vendor/ring/src/arithmetic/bigint.rs
vendored
Normal file
1627
zeroidc/vendor/ring/src/arithmetic/bigint.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
123
zeroidc/vendor/ring/src/arithmetic/bigint_elem_exp_consttime_tests.txt
vendored
Normal file
123
zeroidc/vendor/ring/src/arithmetic/bigint_elem_exp_consttime_tests.txt
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
# ModExp tests.
|
||||
#
|
||||
#
|
||||
# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M.
|
||||
# Additionally, and unlike BoringSSL, these test vectors satisify:
|
||||
#
|
||||
# * A != 0. Test vectors where A == 0 (mod M) were removed.
|
||||
# * 0 < A < M. Values of A that were negative or larger than M were reduced
|
||||
# (mod M) to be in range.
|
||||
# * M requires at least 4 (64-bit) words to represent.
|
||||
|
||||
ModExp = bbad67352704a6321809f742826bf3d1c31c0ad057bf81432abeb30dc9913c896c03e69eb1cde6b78ffcb320c4625bd38ef23a08d6c64dc86aec951b72d74b097e209ce63092959894614e3865a6153ec0ff6fda639e44071a33763f6b18edc1c22094c3f844f04a86d414c4cb618e9812991c61289360c7ba60f190f75038d0
|
||||
A = 855144760f2be2f2038d8ff628f03a902ae2e07736f2695ec980f84a1781665ab65e2b4e53d31856f431a32fd58d8a7727acee54cc54a62161b035c0293714ca294e2161ea4a48660bf084b885f504ad23ea338030460310bd19186be9030ab5136f09fe6a9223962bce385aaaf9c39fe6ed6d005fa96163fe15cdfa08fc914d
|
||||
E = bb552be12c02ae8b9e90c8beb5689ffefe3378d2c30f12a6d14496250ecce30317c642857535a741642c3df689a8d71a276d247ed482b07b50135357da6143ac2f5c74f6c739c5ff6ada21e1ab35439f6445a1019d6b607950bffb0357c6009a2bfc88cd7f4f883dc591d4eb45b1d787e85aba5c10ee4fe05ea47bf556aec94d
|
||||
M = dcc24236a1bb94c71d9ec162a6aa4697b932717e82b667cad08b6bd1bbcbddf7cd167b7458de2b0b780486b39574e749d6405f9ede774a021d6b547271523e9e84a6fdd3a98315607ccf93356f54daa9c75e1e311e1672d0dc163be13f9ed6762f7dd301f5b0a1bb2398b608f40ac357ae34fc8a87d4fef3b961cbdb806d9061
|
||||
|
||||
ModExp = 24eaead5b57883c2f454928f8edd470a344bfe07a953194f7d635d705ef13ddfc64140c8ad6f363d4c828e7c7891a6b6d4df37335de4552c319dafd1c06d1f743240082a3535df4da1475d3eea3fead20e40815fd5a0876c881c162ab65a1eda494280c258901ca953d1d039a998bf0e9aa09273bbef4865f3054663b72d75ff
|
||||
A = a31618b4532f53729ba22efb2221432fab1dbb70853d6a1159b42fd19fc949965c709b209de106a652aa422d88922ce51dae47f7f6deaf0055202e13db79ee84fc3d3c6f4c003ef96597c49d6895fa53c22ac9e4819f7048146b5272f6279424fdb389819a0b251c823c76f4bebf4f1246de455aafe82a0d34454f5039e90839
|
||||
E = 9f43dcb641f3ecf4dbc97450f2bdf3b7ec6a2f3e8e96bb1df2bf34b8d2d78e1a9018d04d960ffd0e932cfc60d3b9b923e3f9f29b3f3d61cae3a9f7245078143475c7fcb896ff200f7d94c4f2708bb42750e37c185a31c876814e4f06a00771707654e1da2fb69c16b6500b16385e3b933e2276ad3569977473f699b1c7926c3b
|
||||
M = cd607549668469b792f495c141e500871880b0611c8004293a561ec7f9ab6561f8a9b90872742386adafb5cd1890e8204ae12aec529cca0a9e382c96439137f09de9973b12c8492c62847e107deabb7dd946ffbb9d0ac73b462c481092bd65326a17f21d8d6527c47a5dba50aaa20c7048b8788a49eb3ea5f29bd5cfce24eb3b
|
||||
|
||||
# Craft inputs whose Montgomery representation is 1, i.e., shorter than M, in
|
||||
|
||||
# order to test the const time precomputation scattering/gathering.
|
||||
|
||||
ModExp = 9442d2eca2905ad796383947b14ddfcc341f5be8fec079135c36f6f0d9b8b2212f43e08bf29c46167ff0fe16b247cd365df4417d96cc31c94db1cf44b73b0ee3ebcc4920d9b0d003b68e49c1df91e61bc7758a8a1d2d6192ff4e1590b1a792f8be3a1b83db3ad9667d14398d873faf5d885ec3a2bef955026fae6dbf64daea2b
|
||||
A = 3a4b4c57e62c5e9d1a9065191f8268fed9d5f6f424d071acef66f0662b8210f4c029ed991512e40c9c912043c816d2c4c5b53fa0e5c253e16808aad4225130dafbbb89fd4f30cdfc1c2f2179b636a7ddc4be579795820b4b9377637bd8a21a0ef5a90d0e0f865321eee23d9be2a3b7320b4012d02941b892df2c40bdc85c1898
|
||||
E = a2c56ea1362511cac0301918e15a9afe7d37edd438a5c3538d258ea01f0a6df758de07111e868b3ad8fc89b629b4955d78a1b3af902be1806410ddde25ccc6a196ba5949395c1ad5d8725b18815dc1cd5ac1c7dd17773f571e3f2e628255af14476e0494be23a4a4dfd18e23142f33d7a59c236fec61660e360d9676a747c69f
|
||||
M = ede35a3a7afac817d413373a2032abbc067b1493f709ae6e1282ee5469743391d891b904938857168802b7872d3cd7ac18ab249a9e540a86f970b1d0f310a4cc29df1cc9d4063d98c554f1a32f4ca5eba3523cdfb142e0fc609907c7a92bb0187009d97ec471db3545f42dd5fd29c07b7816085d09477ba31fcf90084660116d
|
||||
|
||||
ModExp = c15ae334455d9f4d1030cd33e734726a27c63624c2afc576238cce5e0498298a4a0c93090a0d19568b41290303c4b558f3d9dd74f9cde8798710f68569ea0d6fd971ce67ec5b54495031de3d8842b8b49288725bee5c9f72b99054d64986ccd4e18d70d5f33943f08cd694eff538f84438ea993ebaba0910c95b3a694f213510
|
||||
A = def633b955a917569df3ba8517455eef0655e7a35985edda27097a063e0d82c7c3a76dc36c5d8a71ba9d540790ddd0ea514aaed98925f9a1808eb288d387aaf9605a9ef8a333ebee7ad7057bca012efd619d5867f02266f65976ef4b16da17468426ac4f99b3e8921707e01b4de20f6f9a068e6a19d872079a27f3a44449db83
|
||||
E = a465c47b0d15d48e01bb8b1d8e3b3253e11515f6874dbed6c25818adf1a8fd927124d5593beb367f685c11e46f18415be73ccdf16fa2e93a600b728163d21d232849e5278c3749d903edad3f1c4535a2f55a2ab65e7ebc64888bd2a0527e876ecf38cec3ab1980d08138709fad8eb88ae65d960adc3f0f8e92f784fe96fcb693
|
||||
M = e43cb9ac1446154356cdc31ec771c79b0e461e22d95185bbe1a279c0945e3af07903a0cb54d553380716fcdcafb4b7cf5dc6da481dc74a8c583d75ff6c1f8e429182d200246ebc473bb56e173787987c1b7fb2dd23f5b2e438a97bc4a1df628bc044fdd1e80c0cf37030adb7b04784dab827d0dcd64f0dbf37c980612570ce11
|
||||
|
||||
# RSAZ 512-bit.
|
||||
|
||||
#
|
||||
|
||||
# These are regression tests for code which historically reached the RSAZ-512
|
||||
|
||||
# code. That has since been removed, but the test vectors remain. Note that the
|
||||
|
||||
# lengths of the inputs, especially the *bit* length of |M|, matter a lot.
|
||||
|
||||
# Control: No relationship between A and M except that A < M and they're the
|
||||
# same number of limbs.
|
||||
|
||||
ModExp = 7f34c1cd63377bc3abf2bb5b2d1bf5f06454e1e8040fe19a72245ce9731cbee1bf9e84532300776c8021ed4f3a8de508d85b4cf320bd82065a013754857b50c4
|
||||
A = 8e4e67da6ff890643d0599387955996ef6f0c2045eb9944576ddb965ca64cdb6247727ce128ef178d4a84e5a56d2e67eb0fe389ecbf691f9244ae80f4c11b364
|
||||
E = 0be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
|
||||
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
|
||||
|
||||
# Same as above except A was negative.
|
||||
|
||||
ModExp = 71fa6a4c8ae75368eda8cc6282c26afa69e2af12a97fb9444f16b7dd6c99e0a5d6034cab4248cae4357346b211039f4a2bc4c5a20a297372094162417af703cd
|
||||
A = 62e0c43f7e263ec85c95ee853688c77bd746cef64ed606994a5d5b611551d1d1712aa93052ba50d7e0ece5a6f4be9dd45321d9f65ef0637f3ef7b186b460a12d
|
||||
E = 0be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
|
||||
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
|
||||
|
||||
# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.
|
||||
|
||||
ModExp = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490
|
||||
A = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725490
|
||||
E = 0be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
|
||||
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
|
||||
|
||||
# Same inputs as above except A was negative. Note that A mod M with a "correct
|
||||
# top" isn't the right length for RSAZ.
|
||||
|
||||
ModExp = 01
|
||||
A = 01
|
||||
E = 0be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
|
||||
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
|
||||
|
||||
# A was negative, and A (mod M) is the right length for RSAZ.
|
||||
|
||||
ModExp = 8d76eb0f8c7bc3160cc8bb0e0c3590fbed26c5932f5f525b48045c0bd46dda287ba5483f97c851fb7c12c2e858ee7a4a4d1af745cbfb3eb311fa54bea12cde25
|
||||
A = 712f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
|
||||
E = 0be99d8f0650e540b9b191e9cf96f74881b902e32ed169ffd8a1776c3f3e80f0ac765aa14615713e1549f250a20fe4ee48c4e0c6176162fc7842a0dd64d640d1
|
||||
M = f12f2c19ee1ecf2c999b87bdafde60eace3790faad8f9adec13b14c6dfb69f8795a1d0fe65494250b59534014b918453042012952ae6f5786342999600725491
|
||||
|
||||
# RSAZ 1024-bit.
|
||||
|
||||
# Note that the lengths of the inputs, especially the *bit* length of |M|,
|
||||
# matter a lot.
|
||||
|
||||
# Control: No relationship between A and M except that A < M and they're the
|
||||
# same number of limbs.
|
||||
|
||||
ModExp = 8984f8c16044f9c0ad7bd72347af90f58e6e003acda92b76e3c7c4a56ea8e918409d8e9b34884d4c89d0b17cb40fe898f2627c084a0f1698e46beccbf6f48eecc281e11ea9e5135adba460ddae157f2c655b5f589ce29b254d43a960a71cede8a08dbb86be4dac22458da232fb1ec2470856827302ed772c9ddafa408c931aa7
|
||||
A = 21158da5fe20356825e72b3f5384ec57720d22f727b27ce2f945c8ee311db781add73bf8fae96b775c909bd22fca75c44c2b0584284a5bb1c07f8eefcd6b0a44047a02b185df34f897f11d4fb9a86c9eb841b4cb8d0383441fdc5af3ef385b5e8380f605d73ed41bb42eb2c2a5704d6034b3ad058dafffce83dbbfb6295daaf8
|
||||
E = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575
|
||||
M = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7
|
||||
|
||||
# Same as above except A was negative.
|
||||
|
||||
ModExp = 75b54540dd6ec1e87c4e77bb93fd50477ea463fdadb5cab05119b34585d18f971617fc1194240ffa6bdfb53e4785f0a451e03f8c3c444aa6080a96af5906eaa508862a4de15b2c55c023b6f278cd04c1e24fd0711244afeda8e3444256e51261ed99fe66beedb52c43c825b4c7a1adc7d4b111e2208ecd495df91e175573ca10
|
||||
A = de24b05c3f93864103e3239f8827f4e59b05414153ac79443b9baefcc35cc12da8de4eb3cdc2f1cf991fcae8cbcb6378f817b6105e09058d2bf6f48b82906f4dc68e08bb05610ab803d6fa806d3a174f8f697afe2223c7ced64a92af0ec9a4ec0aa6c3e7a5fc8d32d52715251d5022aea853e74f95cc44a777f858a1b8a939bf
|
||||
E = ecdebd112b3b5788669449dcddbd479a203ee9ab72a9bb9c406b97623513bf0ab9a22f1f23634d269e16bfd6d3b64202b71fc355057411967b6ac70f8d9cef0a4e06819a9a18cc06bbe438243fa9759303d98be8a65dc1cb13595ee9b99f138554425d50f6fbc025d8ffa3eaea828d6f3b82a3584146bafde34da257995f0575
|
||||
M = ff3a3e023db3bba929ca4ededbace13d0d1264387b5ef62734e177eaf47a78af56b58aacc8ac5d46f5b066bafb95d93d4442bb948653613eec76837b4ffb7991cb080b6c8b403fb09bc817d026e283ee47ab2fc9af274b12f626eda2fe02004a8e27b9ed7d3b614e8955c7e7c2c0700edd079455237c4475fbd41857e206e4b7
|
||||
|
||||
# A == M - 1 == -1 (mod M) and the exponent is odd so A ^ E (mod M) == A.
|
||||
|
||||
ModExp = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964
|
||||
A = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d964
|
||||
E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103
|
||||
M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965
|
||||
|
||||
# Same inputs as above except A was negative. Note that A mod M with a "correct
|
||||
# top" isn't the right length for RSAZ.
|
||||
|
||||
ModExp = 01
|
||||
A = 01
|
||||
E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103
|
||||
M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965
|
||||
|
||||
# A was negative, and A (mod M) is the right length for RSAZ.
|
||||
|
||||
ModExp = 9cf810b9e89d5cbc4b79ae64e123ea06d92965e2bab077df97a1b906dc2e1ddcf96a9c4ed14e2cd96309b829ea9cc2a74a7d4b43c5f34d792a7c583201427754b8f78b783608070a84b61f18913e3ced7f7f530972de7764667c54e29d756eea38a93cd1703c676a4587231b0ebfeadddf908e2877a7a84b5bfc370ecf0d158d
|
||||
A = 35d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965
|
||||
E = 61803d4973ae68cfb2ba6770dbed70d36760fa42c01a16d1482eacf0d01adf7a917bc86ece58a73b920295c1291b90f49167ef856ecad149330e1fd49ec71392fb62d47270b53e6d4f3c8f044b80a5736753364896932abc6d872c4c5e135d1edb200597a93ceb262ff6c99079177cd10808b9ed20c8cd7352d80ac7f6963103
|
||||
M = b5d257b2c50b050d42f0852eff5cfa2571157c500cd0bd9aa0b2ccdd89c531c9609d520eb81d928fb52b06da25dc713561aa0bd365ee56db9e62ac6787a85936990f44438363560f7af9e0c16f378e5b83f658252390d849401817624da97ec613a1b855fd901847352f434a777e4e32af0cb4033c7547fb6437d067fcd3d965
|
||||
13
zeroidc/vendor/ring/src/arithmetic/bigint_elem_exp_vartime_tests.txt
vendored
Normal file
13
zeroidc/vendor/ring/src/arithmetic/bigint_elem_exp_vartime_tests.txt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# ModExp tests.
|
||||
#
|
||||
# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M.
|
||||
# Additionally, These test vectors satisfy the following constraints:
|
||||
#
|
||||
# * 0 <= A < M.
|
||||
# * E is odd, and the number of bits in E is in [2, 33].
|
||||
# * M requires at least 4 (64-bit) words to represent.
|
||||
#
|
||||
# XXX: Unfortunately, the above criteria exclude all BoringSSL test vectors;
|
||||
# i.e. none of the BoringSSL test vectors were suitable for testing the
|
||||
# variable-time exponentiation used in RSA verification in *ring*. TODO: Make
|
||||
# new test vectors.
|
||||
782
zeroidc/vendor/ring/src/arithmetic/bigint_elem_mul_tests.txt
vendored
Normal file
782
zeroidc/vendor/ring/src/arithmetic/bigint_elem_mul_tests.txt
vendored
Normal file
@@ -0,0 +1,782 @@
|
||||
# ModMul tests.
|
||||
#
|
||||
# These test vectors satisfy A * B = ModMul (mod M) and 0 <= ModMul < M. These
|
||||
# are the subset of test vectors from BoringSSL where the modulus is at least
|
||||
# 4 64-bit words long.
|
||||
|
||||
# These test vectors satisfy A * B = ModMul (mod M) and 0 <= ModMul < M.
|
||||
# Further, unlike in BoringSSL's set, these vectors satisfy 0 <= A, B < M. Any
|
||||
# A and B values not in range (negative and/or too large) in BoringSSL's set
|
||||
# were reduced mod M.
|
||||
|
||||
ModMul = 09fcf6a47addfa336557749821a88ccd2573a5ce2c3094a17d9a29b33e043bea165499e89fd2c939f17a670694aff05e9af46836b62c96e597c83681092d63ab9d6e22751aa8fd4b9ea94a90a373876ef0f6514304a495edb5ca1795c9ade7965c70f9aa92f8ea460ccb670e9a62c81e9c
|
||||
A = 071b93fbad39b1c2755f2051ff7d532d59c985756410d58aed3947d6ae737ace5aadc35e7e0d29c684b9d4bec9c0fa277996bb30230f70431cb7b905
|
||||
B = 0167be8381a3392dd4df62e150025e13b388bf366922ba8632614928922cc290772135857d1b5234d51c27862cb1a055c1b86260b6ec
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 8e2ba940fc5165c6c5f7f4cb55cd89d1d5f59e90e78730bd66fb120a814514784879dc43ad4f355030ddb3486a59bc34b601474978a94ddbceafdc0ee23cb18708bdbd824d37cc32577802ac6057fef29a71f168e816309fc80cc46f251e7289c6a57fd222d5868263360af63dd73e7c8b1dd6b3f3b6939849580b9231940a4d
|
||||
A = 1220ac4bde4feca135268550ddc79d8b05ff72f483b39f77436f348c4f5360c22c598f7dfb76697bf6d2ae86c68e90748b8b729b25f932b2e5fd33f3b5
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9907b5bac6168216cc456c082ec793bafddf883bebc38372fc842b01cc47fa9cc16a8f07069b1314f77f20f33130cee31ca9b4cfddd79c45
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 8e2ba940fc5165c6c5f7bcac0e449b64801e75134a390f120acc58cbee43888f50d07f7aa6dc2b33643c025cf745434d20eb1aeda8fcee5fa3fa5baf10d67c21390297857aa50bbcc4a29a6b10885f97fea60f1b88fc72512c111b938142ee8d67545efe386622162e8fd50418b09769b8c22efe54fdacd652580d609f0528bf
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f4253911356f785368d3bb46a073963c8beeb9739df5b75cd3ecd3b6b228a6757a7444b7e06442c1cdb66aa4c900722e807ae756e1c21c172947c289ee5a295
|
||||
B = 74147c93e729707111d0d531b1c135453f3e59f63a7e082b43dceb8b16cc5debdb6d7c0ce0c00ec9b5ca51e7673e411c3cab34938124db6a
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 043c47d7e319c32a758360dd726a1d91e2cf5c57f73cdf9ad2040e61a9c282a2962d96d300e04288461eb1ed37df19e6b88f104a250f9885898740f6487b081515314e0a217df2d4345d3cf81eabb2bfb346b634b9c251624748f6e9407cb677aff4c53fcf42cc027de267e6ec011e14bc7f3bc6666f693d21
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4d5c014b0eb5d5b5c839a5d5b7572ac8329de6665a5a87fd00e438d2441d47dcf1b19b535b18d53296dcac91075597851013912155313915e06865901ce22d68
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c623c36607369964fb48dd46fe84d9dacfae837c588fe9a6bab47cdb7d1219fc57a5f62d44da48f835937d1a60c9d7f1ff5b4e909c4fef5dcf7c00
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 768293c84c431b9c8dc6e538ca3f856c60ae5e1aaf42325865418b7bed16c7fc2589968319cf41cb370657c8edc7b969de10e0566b64ec796470b630e22477e7aafb38e99b6012f100c9d23d5517d486e3cab1fc60c1568c0228c9b55d2d77d23b1351fe37ad4fbf9c07f29330a539de4a32709d043dfc9e21aa1a
|
||||
A = 06bbaeec78b6a41818b7eec42fa3be7d639dfd86fbace2bc14e0369dba6dd3f04ede8b808743d809f43f70f1146dfdb1d649546441919e27f1f7a9760da4a3b152
|
||||
B = 1199dc2f52868a0cf440f6666b576541c7aec1e9cee14c1d22010ab0f53fe8bbf3029c639ff78d89dce82de85fd8eda4e67395d435df60158623c5
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 8e2b90afbdafa02ce68d537ae807b4e7f3e05a66b20b84cff309941fc3150f99d083841ddaf6f19f5a76886ad5d853c73051a0457e95eeb0fe3776a084a027ee77d14f3825713a59622ea163a679cff904db33bf6ab23b06eb4b31f4e34fb122c8c170321164439db783e7bec1c265eed33f33bd9cb6d1611c00aa18a9b4b90d
|
||||
A = 1c4821515167f7073d4b7cfa318ead1da1131499c12497447846caa84176a9d4af576fe549fd8b0f77bf8dbebf6c395f84dffd40400101bf28b1dda0bbdcc5da255e
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf557465589a08cecc3c6c45f7d537ddde56f33de3ac83426348c53cdb3f78d4dfbf23f8902b8839ee1bcc5ff6faa180a5dba95522a4ffd354f07491cbc2
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 33e8e8e193b4b99d8bb382c29c1fc5403190d7654f43cd77e28d1bf77bc3a728dde9de9a89c6522ebc7222d25f46833fd1753a44275b04485c77b675d816090280b3541ca61bfa33921a79f7286830131d6eba13acc46cc2c449b3a359f1cb49d67a4d0cc1245f3f8b59b1684aa0c3ff1c928b8e880a3375ed811dffc991fd1d
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6dcf2f4d4e43e42756582fc51bafaafa1032ec1edeaa1ef606bb49906b5053a72b7a1e379587d75eec2c84cdaab7a419d60ec6b4fbb0bc45fc4ef8dcdfb5771cddbe1c8f
|
||||
B = 049ff858c7081392defc3ba12ea8869fd61188ff15d9339be72657b00530b851de53b1fcbe16034816e73251fe1ec97bcecd8bccc470373974287ca328af
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2c88dc40414969e8b614bf8db05fbc38fb2b7ce144d7e707f9f8eca40ae2309c1fc67e713a8da5fbb20e808ad20aeb369cb72a77fd285e38a7895ec0fc795ade4ef1f1680f3a3b3cee4569cc9d5e699984daab3385815d2e515ba5d67d21dd1defc12ca81bc8ea645f8f8d103b4a0a9cdc92eb50690c07a037df274bbd5217e4
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3e06321ee2696a19ec7b419af70b234534841284d8b2775789ca6e8ebfd01171ae8a064df04a074fe1003967eba4f81c805fcdd2d665a0fb1f6d58c20411cb5fd820f0aec9
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f20c758c506fa6efeb577db1da2f76a34fdc71c83882bd63ab72e7727590a1135337032b5b2538d79f6894be4a4561f8056c95410047b7b2b5b68ebad20159e
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 0674885ca3ef617a53eaedb9564cf96bcde131760ac541a81f4b25c174a6fe1444c2c206f7171e343e1bb43f81610162994c497419e75aaa25b664c122ed2b27640b45bf646fc5da1703fbf1cc66e10a3c306eb69ae5f937081a1a18dfc8db376ea18f4c1c499109b0cf8806eb32cb1f28985da790047bd7b32c1f67bffb9761
|
||||
A = 0413cbcbbb5851a4ae12555801f7f80ccd888bb82ef1b5c31b99e1901d7e0ab91ee489c84044bc21fa2010f11aac21d0531fac09feb482fda579cb9f224c3149dd6249b0225a
|
||||
B = 01b6bfea70f1d80350eeb45f9a5cebda954d72cf5cd27a299ef5a42e1ed0b50a541d1657b70e50b0cab69b22e31d0944fd735957b1ff764865d9385af302bb802b
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 8d74ba5fdc67733ced4d468f6eb6ec4c1ebd79c97682c1d4daa06105788ed9c5144992e555d903804d7ed0dd9b29ef2648568ab7ff462a03e0bceb5482485afc3b91448fcfeba435dc587db6f3a022428d37fa0e85392d0e48e7d4ed6b21253084e653da8175587b3b709e28426cddfec8d9dc582d4ac2f3d540305c0fe17327
|
||||
A = 17c0b7f0e2cdf316e4d32f040e26d41dbde1e6689d98f0652da1c380daf5dfeb6a511b72d82f1b32d3852e9aa2f594be10776a8fc89a8a35c160e8e41b42a06a342fa1c309fd82
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e20210fd8419b49f890a1a7ceb4118b85670e3ab9a5410a9c26f852de0edfefb003e303e4d06c2398d730641a5849ac5cf7984febf3a6465387c6cdcc348d237dbaea13
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 57e60f79b4e156ccec4c253e70df8d86e4aef326150d612a5ac4dc285761e88ede412d28d9dfa5a6f5c073d3c91a65ba9c86067d81f296935f0d0ebd2af82e7f6b5b336422429cc3b8427fd8d3f5a6fe936f4208362632093bdd3cec1aa8f4b176d260f605caf4a12cc011f3d1b76135ac2507346674e41673eb16c0f55d8010
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7ae0e0f17d667641f443e6a865e9d2597d7f2ae957fdc4c1f68bf280d032bbb325a2fcc156b9c3063546008180884fdfb712ae15feeb185252500fc928116539fdb8e9a0b24ae6b39a
|
||||
B = 723db98a78f42aa45496f31cf78695583526d25e167da48ec310e447ad3540be2636813a2c2f7b8c622795ac451992e91bb8e43e5737f0dd95623282e729d815b08ed8
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 0237eb5726e2c628a515104bafd44348dbf099569815784eca5d6a415d3c12421c8c70fee23d6d82f7b5b136b70ffed3b6d9e98cb47854e79239d96c26f2ec955e4ea8dabc29a1b0765c9b7af6ef09ca673d1ee21c680e4b8cfebf47bbc74c993d017ead6cb6f3319ce4de9e9765cdb3ed8fcc57a1b153327e1a6a965e5dfa89
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763ad7e109313b9830bbdadbec27cbbc9b3d25b0f0882bed6846d14770e56874eb5068533b8ff5988dff7d9748d2ed04b670390ead5ad7a060e77c29f040969a229308a27f5e2e33ee9f90a
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3b821bb5db6fee060cb22e5bbc7d2f950d181f1f39642acbebca9b295a63272bc3d7dd2f560ae637ca4db44b323e303d3fe20f2c71091e71aa64ec4c3980ffdebd83192136
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2f1d500443fc4f4b86e7ec93e4d0dfd3faabda35a6dd31445021928373be14c37fec369ce80ebcb77aff2151b7ea94d21592da1823ebfa0af196f286d7a69ea54799573bdcd4d09ca4f33b8a3a93b35de5ff7f65099d59367914f1c79440b471ced6773b0802bd8ca99cf531b62892eb1e78d67f8210592208859b0aa1754b14
|
||||
A = 0572de2984fe2ed0d5ebb5bc3f62b197fd592795d91cb16b48a0c898991ee3e884e5870b92405f248036ef9b3898c5ee6100a09ede5a48bf7edf3a067e4fc77e7e6bf6a6e3d4f538e3d66f
|
||||
B = 12c379402b18a34dc8b80c0dcd25be16c99d6f76d5d64b6050b90910cce594bc022794640735710c7ded857ebd44fe5b2e51574a2296f7d7a61b59c0123051bf2ba4a168cf8f
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 4001c734e1391a88640007893f167eb79ef61e4717d5eb14b8d80c25ed59c753be63fc8e54bdaded22c9c7d3e49753eb49efa010439807dba0d90ec4f9b498aa97f109af542bb41922936223213ddedac4d0fad8f1446498f4228b758aafdf1d9692f59029c76ca2832125ba50e811cb95f2b982a7a4d87b4726e6dd8b1963fe
|
||||
A = 16792909716b581a936287d0a8550a1f3e840935f0f3ddca75aa32e3489269b078fd19a16f8d6b2326eebaf46da76e90890c0ead3b35689bfda8c1ead17a4f672588f982cfd3da2c2b9bdad9
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2f60af132627de89a4bda1ecb8d38fb8f26e5501e4d7d4b7f98a7af2c8ef53ed37ecf8ff31150e4bb9be0e520ee1a212a1e3a81dba46e4f469fa8f2cd9754beb63f7c1af6cabd001
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 1bfad44b58d3f8bc987116d4cc7ac98f89f838a8712d81d726189e9e1469cf46fe04675dc0b82e6e556b02c350ef4e30ec6203c7f1df937ea80f435af7c10f48538fe7755ba78993f304e64ca0d783b0f46f61bd14fd3fd30768f233c59018ce911a94b495f58eb96438e416ca3c7eba5b1bca9dea5a770c1d2d9f2f62f821e5
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d1b500bcc03a4bb2951f3738cf8019af41f326f1cb11a4b994a0d6bc78d8f901434b6ff1a30e498a2a826f80c91608b12b6de650dbfff61ebae61265ae25da83e67ac5bbba6c95e9e70b9370d81c
|
||||
B = 04920f870cf9f371050e64a419ebe07ac92dd3525b41e8ecf6939a267e1ba853d54862dfc95dd21b3526eb0a0a7a7f8fb67df2e9472dbec81e15cb13266257177c5f2b92fced4cea5d
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 6b0b84505907a5ca37abeff9a5ba169975792c69b5751d9845c0f09dea833fb679c8dfbf3895bc470529e0cc736c9b4a0d08b75d709a1d04525ae583c5ba082d3bca1355055c7bb674aa1b92689cfdec4dbac84a96e81c855280e417f60e7e4931ef4f428420c0b85d2cd11c1030a47788d6ee6af0a76b5364fcf23b270e9d4f
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd3033f8e55637ffe56fdfc4cb8360a8733ad2dffe3369c98477e6277e7b303093df796dd63be8d650acc21b259787097a4ffaa8c997da01f2fadd78535cefe9bf6aa9684dc36d05722f4a080f9cad2899b
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da76389a6557af54b3487afde915c649b73b87e3c33d79883c54f73b623fbde12516b52fa84bc2fb0361c09580a1fb7482db75d5718afd8918522ea0f83d62f95527e4154ba016856c10c2ed8
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 6bce40524278ce242b0b5292d27751a3dc414f962d9c1cacb45fa3ee693ac6890d2ff1647abe578c40ea8d4b326a2e0e2fa7cdec28fe2da089338b5fed91c4277cc5be37537eec2f17edbf48a45fbe38f15c58c3e733d408d001262dbd40c9d246c323e7978df4fb7207aa9270a12921743cee2a483e7e71b221b09a6b2c667a
|
||||
A = 0402671b0cfe14655bc650bd35dd0c36ce7f65de274a0cc4b708c6f6c3e84c2125ab2430e702421904950b29aa8a03b049910305127890457cd0cc97a3e05df67f29d28b0452969986959df02f59d207
|
||||
B = 01648c29205f19fe4c646eb62e8ae9b65260c2cb8424a526423c6bc04ed55870cefef9b8ba808f8ed2e1ab170e2e411f68b934abb1a22776969f79f9420f8bcbef28417582942e26646af60a
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 40db38dcdc201648da555f1062bbbb92c632c29b66902eabf90d98dec69ab3f3b28e60cad1571e7246f4c9e6aa62ad26a6d0bc08598c7a8571fa830cae4c2875c5c95a59f3295f998681edba7749b7e38cbece8887a7823b4752165e1a897e638836d408f439f009d0fb6c196e83e83ca3289d2bd0f0eb36b721331e4f9f80fd
|
||||
A = 14361ace8ec5223bf0165b78913b77ef921b7089bb5e28891d120bd3db6513ddc90404a4e6cd027f9b51fbc02e80d376d59e1f2b043954199ef8218bf26cacdc5e749f668ad3b4ab35cd796f94c06307e6
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22555c011f02ef45c8d3f764b2426d4782881936d561ea99fc32451431712a0abfa195b32546c1a749b14ec8f78bbde852f3a1da097fbdf1bc6dec05a2cdc3e020c6b960a3ad6cbcba146103aab
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 4b085796665458b798f824d1c1a88c23ecca456fb88713b433228ca8735141a616633ccec4bc53ea4f6e0c74e4aab6fece2e4cc4c4efb479638cf54caf55d4addf75908076f5fb487ed00d540e5b984acb8f81cae3ef51db926a06382a288092b352793de721c23c371fd0ce7a789486b2e8b867d35f47b5daac2d339d22dbde
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac7127ebd9ddfbcf524d3b79f6b9a32ff89b0df3a496eb286f4f2e2497a75ef26f04c3d9e8a1f461e1c9be3a8d16b8b75617e60104c4970761de1d6a56a5a4281f14c74e7eef2371b8da83767388108f5c0da0ca7
|
||||
B = 4f22597947638b9a9e9b9b7c2a8d37f77259f1bb1c7db65003b6e1a1c807469c84c89a75b80bbe0324fc3aeefaedc6ad9c0d9e470dac9c30bc48f6abbbdce9547ad7624f0ce9ff3cb6be23e47bc7
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2b90a57349ea94ea818207fe15c164f9d3530c7cdffcae178557274552f79c4ab56acd78033a570bd6c3e45789704ef0b0ef586594fe4cae3ccfbf9ceef46e769589b084adcee3ef8345375b7103232465b991273df724964248737d5eccbac558e35e4190112571d3e7c291baa7aa8b1800121bd573b8419f627c0091e1bba8
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac5a2037055e9c8e076e6cdc81847fbbd11f10059d46cc9521b1684f848f706002520ebdd60a8fc545f51a08eaa60872d6afed2226a6f182d9ee7d4314232de1382fa77f5b4ff7a72483cc039c26891df60ca5ae6
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd2ff66f81a2fbb2016b210df612743b1dbdd8ddb2a931bc785a7a6b7d723e9de746f31c260467bd955616176b327bae3aedae613a1827713a2397325259fdfae0947fcee980a13902653a818ba43f1f2d4
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 4cd4da762c7576d582572d3427abc4b4297f740705fc14a32b46347541b152d0d1e3a11f27213badcea1e2009e34a63350c7a59e4d43654b28298d2757d6b54c4d82f580e98de4230cd119ba350416452cd4b8adff29b9f35ae0c533f666cfed716838e2b91941dfbea8d6a978a369d5f27554ef411f15e5a89850655d7f3f5a
|
||||
A = 04f4a28af27b926d8ac347503d6ac0bfec388a6c0b38a577501c3ca4aa709c69601824ddeb5eba4d9e437a97f3e4477e1487d5ce7b4a35b90fb863657a5b2d901bb8c3c838db40b89b495ee9875e8eee607d7b8013
|
||||
B = 13ca192603bc8b2da29dae67159e4f8d32f351a503434ed9e4e24f74abb5908ef7da80781c71b1a5ce64fefd13a16cc1eab05a370bfba2a97e6cf90cfe98d3a487ba72dde0762c36c10e1da175f1c1b5fc
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 3812e9e835ae355fdf328b29ed8b86dc3f6895e379b8b5d65a5de41eab5fb20ad3e2290c8ca69f9500248ff883d9715f59d0db6257d13c5cd612211bb1fb99867161daffc77968bdffc1fe48bcde0fcce02ca93975b3cd9e93b56974ab4beb59582c3d0ef2a65957f701549f8bf858de0c5bc98af3e5722f1450de391876a2d9
|
||||
A = 14ca6101af00d67139b985ac9f149accc260336237dd2dee802b5cc6e506e217b74c1a007ec10c20012f071ddad34e7407012669109ec1f385566ff04cf1a1ab7562353c0af1ba1be0baaef920a188c60db27970f64d
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac7123b1c800e638fc5c56e2bcabb6f12b962b37367d8ab77e87894395ba23a6a525b72f2a4d6f12efd8f24298377e640b5158443241dbad589ef8dfb1f6d36a934e020b303920f2f2eb662429df171f4e3a2ac50
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 5ad7411cef0581b2e675d03b0ecb9969102a283eba5e779bdcbb7646d94e843083a07269c932d18b973b57abe54eaaad0aa76cf7b61f30505a263bc95aa063efb264ae829eb1d1d5f7d380a0b4db59839de9ae6230ba51901e71b3e3d59e8c34a79678e751c8b7ab139123bdb2f04d90a18ed81d2046ae86da1a73c8dae4fc4f
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed40c31b8fb13cde21f2e86870cdda0b4542efd681542a3c38343f5e00d14c174f5ea06b1d018edd9c82d587144eecefca6db5b6e70cadca1ad5ffee9f4a993270e5caa9ca71ed39146901611688a79aff0293477bd6f9ed5
|
||||
B = 04a0d48e31cb8c24a3b2c9c95fd19edbe46823032ef4c97fe65d0a30d5c2cad7a4fbbe89e0ebc9940ed9f9ccb8ab18bac269759a9740a7985809d0f38259e680f0703febe7fa012d1ded47f0cace4a133f59a721
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2b2953981db406ebc544c39dfeb08a8b089064533221536c7fa2bf2a7a0d3a1192859b7dc0ea5036eeab5aa371e3e0070c3980433adb3e3a5202ff257bb546bcb9550423201a35501fd717ed4c0016eb3a675ed399340bac7f058a04e69c1774590fe747ffb9c27e78ba50fcee30ce533a1659fc49dc080a60f21357a6265d24
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05db1f0b382d2e76a22a2788439b6a2d571b49836383c68b45393ae5d6e6f2d73babda499420de469ac6bab7222ce957adeab7aebd3ddafb75189705d73cba31a54d9e2b46391bf9cd23e5258d9ee1730d577d5b789dc9997b1
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d0e72f8ec8f5d254a7147b2241390bcdf201835e1e89d2963112fcdde1902faa8b45232feb7d9c88d8879b234b61429c7ad79b1b60b254287d38d8ed174257621220bd8c1f3d2387721c5f735a7edc8c0f03a207fb60
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 02104dfef151526e072c09a4a277eb981a035379de3b1a55a88cb060681706f26131c388f5572c5646826b119c85ed450207f32733487e3c4e1e9d701a65058c4b4ef0cd1db090495643038229ed177b54695ac32110619038f1c1cece14faa693d88476e3d70329b0084d0ba5d547bbaa5b59ba1ce1fad5aa2f1c11a75bc7c0
|
||||
A = 07b79e6f1330fefffaf8521089c3348593e40ab7e8d4da3d4346571b43b12740958336580afd13619be3dc2d42eefd9e30599405da3e32e7f3a5655ece8b77a367059668021aa092460de75e627526da08e6206b0f8f539ef40e
|
||||
B = 0156e234931907c0c0970c1fe6bd4b24225ed94d5f5b1be4693c8e141e9a6032425b4a47b6eac6265afbeb9d796eb230efa707d5ac4a73808225181cf814b319142e9d175ac461c75e6d479bb6bea53954bb981062eb16
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2a392c5fc96c29df2f5ae9eaf76e7d981dc1e2f3b47b43a98eaf556a9465ae8727c622188123c64658053ec50c25e54ac5c6c8bc279b134d326e911f14c873357647866eccb4f9038ed0cef5082c2058ebd71e1619f7c8f8f2fb80871ebbca3fbfb7845bd855d307d2efd853f1bfd467fbe030862f165e53a9cfa633d0d3fa23
|
||||
A = 1e0430e7cf15173d00592037e83e717c90d7dab4f54a5b2f0f5772762fb5f56bc0b2a53ec1bc3b960afc35e7b043f9d85d0af6c29288486af3e186e52bae6300b58917647231b40a12648cc8c020a797683a9bd7ff34eb6d41b928
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ec64a99eaffabe42c22517c8492c63f6fdfb82bffd693a451d62fece2f56a5606fccd9f3e86e2718417bad2c1df9502f2f0214e12261a060a6934c0ea8483894224e4367246b4727606274037b4f05d5767177f9d4e5e00a8
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2608f68632ef14dc3979725c8cf1a0db10a1651f17d91247edfae9935b53f6364d233b030eb99871a87b7bd876ab2cfd5a643387a7af9d337e81770db04a14f4f8dbda2cff604838c9af9a31e8dccf9277d453176589ba33abf77855b9501e63370b2e6cd22831e1e70ff1815302c0a026c70042957d08e74dfaff940a91a7b9
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a18674c977d9484d2fbefd9b54d9b955d05a6965f522ec56a647bef486f85f59e7cb3bee2a3af6100fdb6e2c17ab1526267db3004084c78770682f4be127263141867fb04692e6feecc8d342b0fee5b9a6eea64f58276ae6ef809c1cc748
|
||||
B = 47f81f65ea1af04f702757c02a175a299b23cd8ad551fdb67020c50cbb4110b5371dc5790b12484e9ce647eeb24c0220a5e62aaec3461a9dcdaf1a22814b6f22d66372cc5ee31944bef33469f905458c172ec7871d9dc9c301
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 5735109bd21d31b5f54e9221bbed78c54cf387e39c13d31557e8173e173f786b2d2f1acf3966c3bf4552fe9bc802d0868a5a7632404cb91609a7a45fe0fb83fea8d83b0319666c1b0ac520169c15be708343359447f2fd37960c1e96d32799ac9394e839b391f59dd347acfb79bcc4e34e76490880d163ac97ee69e3a0a6e68f
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a011d0eb96be3284170951a6faaa10836f1196f53ee084d42a0c9d92dbb378d080c9f7c0ca8e015f323e3e64859a2f9fecc27a3f4ae87fecb8568c0ac2f5380ddb984bc23f574d8b56cf1250a0f06b90af2914e55a68cbdb7084ababad0b
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fc35df5e7c50ffc2283069f8a00ce91e5d561b5d6b06c81dc66e6c50ee1af260eda95de46017effa03234ebd6204e18a009ed2a53c76f76ed621aa6606abd91c0805f324d628b90e4c2c44a0a505911c7b0c097e001fac29efeba5
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 3b4ad19b75e1301d19b57ba9b68e0666c28c7c5c99df1d5fbbe0685dc1d3489ff39c919222719c5d8b7ce2d7ff967730d776a02b36a86064ed66a02011bab82eb575390f85f0104715f6e4954a1bb28518450182a8ef58af35d00e2fe417f07ba25dd9c85e00c3451082becd22e3aa0c9bcedaa96e6423c7df6c375b4c799c65
|
||||
A = 058e1ce4a9b512eb0632b02cf1207936d6707b802140540fbcbbdd712e5ac1426b4f36e74a9a9ddc812e572855d4fe4fca8a0de6644226f5698fb46a5f2a479dfc8b588aa8e02ddb15acdc79ed3d17143e290f1317274f425b869df54a4807
|
||||
B = 14e341cbb5f5a7f3b4dd864172b82ceed2887fcf20aae7d0598b3d8afafd2f10c27bc7456c1488abb570be3df04f43d892dc6a8dbe7621f55bccb0ee3acb1ade989a510b4e0cbe29b6b93968f323f0016d87944c908824d249769f8b
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 7fe0bbbccad6032069b1a335b3f2dac16089051cd9321f903181fad23be6853e2d209958e8c48e008be94a62c6206b34b4e994ca08b8f24a2df0e6394ea65b3b7aadb3bc43d04dc9d35a77e673c4476dedefd4568b4ade5d16f9d89486f3d5ed0566b1eb428cb0b688f10fe3901037744f278385754fca481f937cb630f60308
|
||||
A = 1cc0e3ed58090db55063c9ba11401636f89262d6ec096d361f448496e05181c5f7f2604333f26d511c13534618e90637adc807d622097f7eabfc03266135cb626e1bad20997e72da71bf2b3f65a4973dc27d2a594b1fd96b7bf7ec14b9e4b983
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a0ff4ae3c00601161a9d435c2a6850c89867009c3dbd9b10fb1f640dd698880aebba08c2220358050e51a3a667184b29d8e76c8855527aef2dd86698f91d4b6595db25644529f9cd8daca93fdd773a001a9022c7f825e7e9e54ac770b9f9
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 35d7ac5cbc7e6c262ffa41be168b02a3bde9e112c512d1f68421d705ea34461ce3e0dafde67f44d44cf31d91b38d4d5f2fbf8c6c6a44ec3ed0298dd58f3d45c04346c11e57229dc3d2cdfea02c802732d9a811d7be5e81094d72172cd04caaa3c9d55a951c09f454f42add6e89e2d8a98e124aac86379df377606e7af9bc6baa
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f654d28e889079e28a54bbe330be57c70d6af97c5000e019a3c3e29bef35379584ce4e39dcf53f81f1dae04e2b97e815f4b6be7d2261c1fafe17113651e9a107ac7704a505c55194196e5220178c3d3337bb072a3b53ecf0dabf4fba203df9c29154
|
||||
B = 072dc8973f7af7122a05c90df190bbf1e39abca908c197590dc7ac41fd0712f48f838ca62a72a177a293ee6b2afa7a10c21e7993347c3df4f161a5641ff62ba123999bf1eabef29ec0d33ed0919818f4b7c35b5f41e654759fc9abdc0f80e7
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 5d83a9b34631dd6c63c05a0c012adf97b4d0f20f61907e1c2145330211e9a7e38128517b058e0a85e993c385068d1cec768deb814bea1323dbd333de091ad2cad72431f20c1e70ff7e1b119768ba44e14292c38b88dae7e55ac9e10ff98e9bcd5f0ac05af499196b4be0c6222d1a63227ee895fa6a8221a4a182a1323183cd7f
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff28887b65a61118c8bc013ad24480a8f95b4e695fe5ddc014ff85bda86629d4b36c066383f76f18d5962474674a62646e7d30bce6b05edd6d8dd389eef93648a230615fa9459bfa8f3f9637b2629900e7b73feb6fa7b51eda0445f348f3658897b6997489
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a38c040ae26eb02ce1dbac7096bf004a4b48fb3ca9a1c117535f261d0aecb063712caade24be40e2605a8e204d0da58bd95d36c86669b917a483330b812af4528dc0a070aebed4a9d2aa09d10d5b3c3c171b5acebd87a3bbbfaa2c16cd7245f411
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 7fc1c65eade94d9de7440eb8dfaecf1004905135efd4f98257c3295b1e76ccf1e2ab6808d158d360b7419c6210c50efe960610973d9ae855c72ec0e81d423e5863c80b542ad455700d2d0dee5fc403dc01eab460c24687401cf6a3179642e59f2a30268df95fa80dcdac230702352bbf6b60acb9ff5d45c5b09a3403b954d173
|
||||
A = 07906bd8d3bebb1303c1df1fea0b2503b0abe9c69b4f4f5bd01eec9e314788cb7d44b93428adbcef570477e8ecac2a64822e481bdf520fc381e1bb0b2cdae2fe94e484cef5236dd524e4dc364b72f4c06d57f29dd3c5079e532b1ab1e71dd6a65b3362df
|
||||
B = 01479ef2807b9c23c094d0416f513894cc92e023b134f44a5333360dbbe98b8161ab899302f4fa11b470b97dca0c4e8ab7ae47e5fd0962834e6cc1763618193f4ee027f667368da580c623080de137b5869c3081128e6081b9d5e2dbafd791773242
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 730c04094b1ce944588e8291f7e6cf763c70b79cf362dc8a1bc63bb8790cd4cfe4eb51cf15a45a8464d69ddc3e1b9383cfbfd643f317108cd9ca6a6eaaea177c5c8b6747bbf40108cbc0437eb8f11bd2a0939da59b70c0c6129e2c249823897f2ee536b0427bc45035f121d2cbe7441c175899b97c490e6c3ca01539bcd05848
|
||||
A = 102cf23cc3b81785c73ac3613c816de47fd585c7d5f175185818dbb4bf0bd47d0dda9702bce97b29d66e48bfaae0fd07b47b40be2b48ed702ef21c54b10bb927f9d6b43604bec4f4b2796b44aa6b4e83f8bcd00f2fa3871dd901570e1a32888d8691454c40
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff287d316f18074f0628caf7e230c5ecc2200108b30485917287ed9cc704afd58fa98a44ef04e39c6760fccfb16d9da1b5e6101a38fb24e6970b65e1546cd6f8c87d8233be4dba90ac05725252ec7b8d407c5fb05ce7e18561281019054935f1439dd3142a
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 1cfe1842a53d00e4619265e2fce7cb566ffbd912c9213925d01408a956af304eacb85e29fb6edb812a95e90769bf1c3d62b0cf6cd5bb8f8992391d2ad70f38a14fb9d1d1eb522aa7b7fd9f1b52790beebfc887193882377b7ce567d317d8432e1d9a908d6ccfe8d2de7de497d77b023b3959cc042ae30aefcc0229617fd2a146
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f12c2038c450fc51fab9029d91eed64b9ed4ce05fa1c99da1acf103668541efcafe7bc7d6afb392b2471d699203a7feffe5471d883f8b1939b6cb3b80fb5ab8f8f51d382237a7954578d2caf5728678ad3b3011392f2d1e4f95d3e40826e5e3c45763ef941b01
|
||||
B = 675d9d2a05288b438ddcb330acbd59e4639375f3f14ac2d0e9e8b72de6ffc1d217ce62f997577f7eaddbe4603541b132cd41f2f2740363d9c331ef22df92029d143fc8495ed0152b918aed7ff22f564c7cd94fd3fe4178c90365ace43def8fe30ab05c0e
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 83ed1948276d689bb7fde814e67fcea72c4e3509c48873c3e7349a8fa1c08ae11ea4d814d8deb1021eb8b8ceec342cba5002a2ca45d5f340ae1aa500af4c7db120d0402c6cc8a840404be7221bbc46ffa10236043e5ce4415d3ef1355bde26d2d26eb7127326d4b8d671bb96a08e38a2c1dcc281830ac77202903a5e4777ff02
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d1d0e8176011cf118575177fee3174fa27b8a90e74bb861627460da83e4d7d6099a9c6f89cabc953ccf0e86b78834b1e60571722abb4185bc42fbe61ec2112cf4d1be7c82d73d3b97c6902712c48b3fc3af8b5cb033435ae832d1d34f91191d4db0d84afef943dcf
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6bad22ea470bfe7098ec697270333ca4e149fdf57e32c9ea8a35849d394b41c3d2d62feffec5a9ea8543927d475bf5f2e9093879de6d599f6be17e67916a60f05711f2655bd8555881a01e0d230c8e11b9a6f157d72f826f4a6f66697eeac3e5dc6d53f117cf
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 0402525e19b6b68942253d1a51fd9b2ca36fc84cf938d80b3d52fd4302de142b9d93d1663e89340fff10c2b5efc8cd47fc3b5cc5ccd49a6ea3038ead6454bf190b7f88f52c56bcf00c6ad5b0f5dfb7615915ee8af137dd99cd3d21172ab772f36d291a6856a8e7912750139c09aa024b930a0a6b9eccc83c2c5c0ee2473ea32c
|
||||
A = 065e5db532ecae639bd56dd63045bca39b33b4d70b2db82ca3d0ee8ca436e671828cde80217b48eae7487fe110830589ab1be889f1e1463f3b0757d529b2f0cdd2ac92c35e8ec141885bbefb6040a3b5e00e64a541913a38fe05824a929f8c5a2c46568c61989c3ca7
|
||||
B = 1d9c73eef8373cbb1e8393feb26d55c33a245c33d7031c234abffb2f06a1601f7f3a79ef1e8664c51ce5dba5f5aaf3b9a9e42470d381219b4616ae93c7f6e64792d23bae523b6a224c1f714ebc82a11f9be42618922b8d2eb7b55e4d45572e68a19fb0ba72228b
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 7a9cdb5dcdfb6e04351057d731fddb9e85f41eb432f01c0d980673d294d05ba9b0180133a89930e74cfce78ed54991b494a19e7f80f310b85904784cebc5639bbc631e80751807868e7fe16719e8ffcd1f2cbd1b9f303c3ed488b647670be3080668b5fa0e53b6342c33c87f0ca1efe1ddb1c877bfe2556aeb61805b06f41343
|
||||
A = 1e412c3d66aea2c503f3aa5dbad368a61d969a2951c0094f9da32d2794e47f3bf4c481ae23636baabdebdcf0753d431426b1865e62de8eae7238a9245d62820ad7f17b5380d701f5db776cd4e1ddbdfd542901731ffcea5bcdc247fa9c83f7e08a9389e5a76d38be21bd
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c88023b951080528d09f2da8c2fb8ed7cc736044d8e086f55c89dabd2d1a0ad2221e9ed664636e0c285375266486981175410951c1690ead03896dff707b60b41f3d9d7588379c93a6e602e3b56f15c017eabb3e12ff4942901cd927fe6b1bb93280fff775cb0f18292a
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 712580a1ffde78c8cf98ba71843c8130e835fee3afbb45e372d04c04cc388e403c9efac742611d7974bbae982c3aadfd1893f5da280afe0c1db1d81a9ed73b6ed9b7f05a20ce828316103259112d7754560d66733041e9470ae0d4dc95fd0484bfd56d66739f38ead7efa4051187ea41f7bea8fe5d958a29af41328246e2bc35
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651052030b76e95256709f642442e56d07be9c4f098ba79856b80eb6de39868758869ffd34925ab6a807b64fca9cca893aa44538585a76a35bbdd7fe09df9c553d8c17be4764662316e3dbf0f401d31418c4340fd3414fe4c599b8536b71d51d430d94430ea2e555860a69495e
|
||||
B = 05bda68c0a64218d3609d75eb4832d5468298f19498507d7d515f4c410f04dee535947571a5e75f1af7f94a5b3b05fb742fde23e7cf3f8b3dbee0a569e5a36d7a3d31a26c4a48a299044fd72339d2cee1a68966c851e76b93ae34130b75f4abe4f2260207d2254d23f56
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 4a1a514aa4d1ada84fa841d0b668930c904783fac521377a7d622201867d773ad23dbb667e0d4181616358f3cb088cd157c8e72bcd03db64647b37aa1813f870cbb0318ae0a3667f8e6c19f6e0706217646ce633f0cc8bf4e8f0f4d7329a8647252ca6d376416d545e73cb9a3cba40f8f9465d85d57c2481b84b6d95dd42d50a
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687633a0deaa80fa8b7717e7f26dd7834679d52e58de4905c032e7fbc427b4ec183e2287b2131071fd68a043c279e7cf1cc047723c6ecdf1bec72c54926c3cd6229b4bc15afebb90530b5008a8ba858f98c247bbcec545dd495b72768107cc98672f7d04fd8f0a7142d47b38462ab
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651064f6675d36585a5f9d7264f3b9f9dcc09c4911928783af66bfaabfa2bc7f530dd03ae6da1cea24776877c409f550267d02e13105880a4dd9ba76fd026d0d5de495d4c74b8021bc08d9014d6fe01589c7f757513090dac2d8eaee630381a912ecf9bab775fc740f1905ed68
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 3fe24e66e381eca525b24cf767215837019f44ed4fac6ab118d02cdbd658066505ee5b0feb7af51859992ecb97d727121e38873f748a61d70201cc43228a7732156a80dbe399e05764be19e37dc1b93222bcdcbc45b1a4817460f7021dcf1d70e632bc6a306628790201222bb522f4cc80adcc907463a539b02f74004d42adff
|
||||
A = 0773454a43f495959dd55b8a064d70b1b1ffe45c084f5f9553582e24fb402b564de68e5379a8d9d02af101594e717a6c6db2e7173e557a64d2f28fd45c4e06041deda040705d99acacf8086830af19c7ab5e27f91738ffbd937dc27e5b7869bb6caa12c2d7930366ff75eadc570a
|
||||
B = 013d884a2396268f1a8186748a15722156a172a56dd3d8c77b9cb7001b6ee06720653507eba9bb9918f2f699cb37f3b5ae514f5180108a704647f19b0fc075826153edda66dc1105c1008ea8ec6f8c10057f8e8e479e1a1274edfed9ef719b30827a30f26da78820c3696d01aa
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 715bab8708e53f76d2ef2afbb845bdaaf978b54ce25f84dbbf9074f16d30a18733a02a4ba5d7b092fa6c25d3b9b0d8243c743910f1b7b785d9cb02343fc6d59eb0817bcff05646030ce4fbb2b9ff76781cb1af66b46553d365d02c61e677ae97defe92d057d4378dadf8cba9824b0022c086e0d78b5442bf3d3263ba22c643f7
|
||||
A = 168186208c734383d472374fbedc2d5d430e85690a4881b740008623120a4f7f83b2cdf85dc28bfaae5870abcd7ff1bc782ef11c78a75c99d41f8aacb52fceeb5f10266dc65eb00b0868937340146d8850887686d54218badb97647a6d82c0c6650ca1f9078d73fc6222aab95c2967
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab67df3f23e8f1b6e4395bca9102e09a76464a81036886a8f33e4f75af3adb74cc993cfdb32c84315ddb22bc1f52a8c04f728dca7f207ef3ba232cbd06b2c1bb63f0f89f2d72d59bb287bd5b164e2ce1bc18466876f9ce944d3be34706158f037d3b63b40546d720406da0401b9615c
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2714b99dcde70d6c3be8b671d78abc155793f13105fd4b7c5d760a4c68ae89987311dabf2a9238d18299f983b8aca69a9ce398fdf2c9775d90b11b3dba17bcd8edf661efb6e9c50b4e37553cbecb54eb214fed1d0847287732810e550a4c86b51d4e5da1cb7722ce4317e69644620ad806d6d1c94e1e3fb4d87de6178a997453
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fde285936891917bce3c4bc572858192433a88a5d77e63bbf31cdcbea067e71dae417109d3ec4a96c9ea4e22a0b88cb25404e003c22ca6ab49083b8bba437c6cd501c5f268fb4a1defc685eb8fcd5d23385501056eb8d77afa5c628989bc33e9d7743d69125f1e77c40854aa72e58ea6f313
|
||||
B = 5aadfe65df0e5b877fe45d42d7ca02882cb6c686d486374da5ece6f87771675153c84d74b6f40df1db567b7e1e3c60c41d21816f958f5576fd2ce2f84a8c3be4749dfc7e5561266b7c9698c7581292d0d813cb77955458d63bf94ce87472924c4ca79504d1ae9d5f025c7a2504156f
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 6613b1c8ccac0cb8fe2f59e76fef4dd05acf1f1b2bfc20aa3f193622ce3e9d4c7824ad544477553bc68f05f0b546e7c1ee87301e111af7929d1f40525291b88e211db7175f4e5c0953141914fcb4fb951dbf77442e7cb28fde495704f1b5141de1e50fbd0e359d0d86ad709c8f564c84dac81c7602717c269219ab1cf12e809c
|
||||
A = 8e2ba940fc5165c6c5f7f4cb56a6fc26f72d0c623eac124cf0cf551b1c6934cb1882967f9ebdb5b36cfd6d1fde5559f584db39a0ce8461dffbc0d35ceecba29e71605a6024f2049603bec70181c2af20b27e308910747b11efeec8a65d2ca886df718062fbec60bc322c6829801e3c3b5b62d50a2dde0c0075eb335097a9d9b6
|
||||
B = 8e2ba940fc5165c6c5f7f4cb56a6fddf2592e9a694e5eb8353684eb05b940d5f643ace64314e1b29324f2f4a06bde7f6e4e84680eed276f8eeb02fe242dc47be6bf5eaec2edf36d4320db0cd22e95cfa5ee71c86d3f78d43d9a865c3a6a7a007afb98052c033d7eb32a0650810b3deeb9a07f2413df201b4741ae0fe1019f3cf
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 3a7fc5680aae875b9241200b9f4112a82cd624ffd9044138ae3cd65200631ee9d7b918fbffadcad7e598791a9f0bef3e23005d6bc0048ba92461283492df3bce74c66e417b082ee052fd8f808d71f3ab18f9ffc40f8fb51ebbb936d09c26a3514bf868141f7cf238c1abb3d88e5d50dfc188902254f07d63fb8cb611ef8e4149
|
||||
A = 04a30f32d467b29dc83b40bca2fc4ccee5f08a64069cb87f20e63387b2219b12aa312400c4ca59608f50a71d2535cde40a6d248290793fe01693ca40b93a5cded2dcfbc9aeb36e187c9d650782d12bea917daadbc6525f266e074037803e4b2f300778ca8dcb304658cdb502c93c94a16c6261
|
||||
B = 1ca5e5218dade077fecb81d579e1c9290431b34df5ec84aefaaf233d68f17dcf60ee010db26320685af13a821b6daa9d73d8f3a30826c3ae7b2bc5e219cadcff826283cd7dddd04cea7a5e0585d6e7c9f23b27f14ff815fe53bcd75fe700b1b91671bddaba737fb43bfecd2a77e5b752a206
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 768d312175ce7d2601f30bb38339f046e4c2ba5c19ae5f7ca5a562cc2462c579fce9985e9e8afe2578db542c8d9e7693e0c74ba161334b249ce720d568e9c18f09c87cd701e6f2080b752362f2fe6252a1d0caaaf1fa18199776e4c6078d89d520b9c63db159d5fba7e0838811e68794b1413c248f3f7173ef29eff28f15b656
|
||||
A = 149353e91bdb70cdca8f06648388508511a64d05221305cad7187ea40d9ccef91fe17ceb1e79667bf66e8e6b7a57faa90a83bad119c02984a8f860bc1f23ffd33d4ad84896610301cd2e8e80a5ca7e8d3ee63e7dfa459793c9dbaef3569eb4f8a021c6a3d032a9c94d3f6b8278274d0088a98228
|
||||
B = 8e2ba940fc5165c6c5f7f4cb55ff32279073391a0e6c975206452902a8c522f8e8a014bcc239720c346bbf7df93506eb95ef2f322138dba8b5df6db51c3a381fb2c2ef9875f5cbefba72732dff4da6144c8f3564e5385f277be7a637252a880bfea80ce2230b88491c40db00f1138a8b08f830a673ce4a7cc1d9f38d35b283b7
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 0763912f4b16549e6ccd60eaf7a0a1f64d9c3bc83e4a9b87e209a3959ba3cf609cf47183bc543f08e346b6e12b8bdd5d1c07c603f74b286ad432d58d7001299ec7a4dcdb56ca875dfc7ee5c75bcfe2aaba14959bf3facaebf8df92bc12937cfd4a4865b3dd74b243ff62ba256d110b01b4089730cf48efdc66fe272f9241014e
|
||||
A = 8e2ba940fc5165c6c5f7f47d631d62a2259a038a455598cf900c13317339e33a90c42906c2f9cab8056b5137a3a5220062c0c6b3bb88ffee3b4ab453b8134e976a8e7c3785bd223c31c96f46ff59705e688a427b8bc6e985c755963ab731d779bdd1aa54ea223b62f5b707c12efde079d98187f7d7edb00bbfc0010f889709ce
|
||||
B = 0450eff382e73f2f38bc3a4abecd5f8de478f80a6b99fb6252173c90d7099629afe859442bb1f796855ee9a2940f21d1f9dc44f462edd74b479e1f2926ff6faefeb55adbc6152b5c97967b1dc8c44dfb85b5e02e870d2920b75422c8a427e99e35e2a4be92cb0ddc04cb7f4044f716be97b36f045a
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 56ef57d56c6d1b94cf0fcdedd3611a8ee444c2e25522b9ad175587619598da341916b183be03b1e73be300f9969120d8f3a23750cd8c4ffdb87124a2139e8ff2c15d8dc944bc3c3a066aa16dbe6dba4a74925e16acdb2b2e83cd7fd5cedade6a7f7409a509c00dadc182b2860609cc9a375cb8bbdcc350bcb2c0df9b3bff882e
|
||||
A = 8e2ba940fc5165c6c5f6b1005d11466abfa370afbb80500e54891dcf47754289eb6dee4eb33b8f37749ad543fc8a178a3f580832b977d8aaab2ad01c57e937fbe73efe0aa2ed20c938766a5571eeff14415d1a954d3f26d7ed1063eb01ddc0ee2e29e6dba9ce9c9d4df20eb92b0535857020cbf05c56113ad072c3a167c34056
|
||||
B = 8e2ba940fc5165c6c5f7c4a55ca1388ad3f286db5f7286c8ff8877b65dca8d7802812c6d30da7b2d743eaae7570493cc8d40c8ea51f418261e84880dac7ccf0fd1b338a61c576eb456cd47b4ec89a3ad6c689f58db3b3668938c66f850754ec3bbdcf95346dbb440bc08d1b98ea6e4e4f7dc2a9ee93a836587d6973c4121d326
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 42f363c34c20c443c1ea7a1c54f98c6977b6671164a80308000533b2404a7f280adb1f3b98101cba25249131288f7ac68b0ae2572c7777e7381c1f4d05fd82188c4b1ed5636652e0bfca4d096bbf4189a9358b79f6b6333b99e5c4b7a940c2f7d1413bf9f47a2ef66b620b5e220b2c3dd7267452eb1b9d8d9cfb17bbfcdb6abb
|
||||
A = 0499d05de867bda3118a8cb82b80ac91fc505e0fbc6c7dac5fb61713cb6e715f56a31ae8af4b400461d7ad1687a2631faecd90d7829f67d1b9e36ed7d55704b3f2aea65eac061172d698384daea710ed92cf1140cd4da427174bebd173c2ff1675b2407a84649b0a318602f33105006fe4d5ed8d0e015b99
|
||||
B = 017a426a12a0175bb46bf7a7e727eb5238af383cee6f4d5e2bd82b0d29b9fed35f3d8ec95cfdfcac49bee47b25d3b5f375a3340fa83f8dd9330a593a974d208debb7e567e59dbb7251b54e42dab2cd50fc63aab050a41bd88282373f8195c94c35f61bb48aa921f574cb4ff0984ccedc070efea8c46e5cf8
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2f03374e9596cb56cbbd89794090ca7a4b437f4c05fa38a09db60e5ca900b208fb85b52f71c29fd35e62c9f9529d7ffe46fcc54607ccb07f6f8e13fdd4ff1185033ba4fcefb1ed4bfc42c3ea9f05276767d8dc9b7b4aea4c8bc0ce84951d1f590cec0751f73667db19060e2bff64da30fc048a1f5700fe3f489920675cc3540a
|
||||
A = 1073531f678877ba854fd1e7f857659614c526847ffbe8ed131dc9f2ccf69e1f1e917bb44a7b905f7ff758f61c06dd59ee09567d9f0df2550fcb98b776ed1381ce052988aa08fc5153e31c621c6a51ca61b386e3a9163a5cd69608b3e200476a8ada35d906c41d044bafe71ef5c6f732935f15b53bf36f7ef8
|
||||
B = 8e2ba940fc5165b8e2a1bba60f58a9da18716f19b8a69f9e6dd8a39c39ad4afba8caaf2ee532d61955674e56751994d9c656debfd5b8fbf448362f09feee6bb9df2c31983cdf1907dd8340ecd309ac805b9beff1d5d9755e2b07d1a21c7dd093691b9b2b52ddbfcae977b04b6842c6d8770bb890183b60e33cb1c9425f43c312
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 01aa22f9013bc1cdebbdfecedf710c1bcaa41c696a3d7dfc1c8c601fcfcc1c85c8cc24be7df2cf3c7311b3b17a4ef2dbce545dc467d2a92d371e02a196a9977cb9042b236acf99d8c0d34a1c4dd8792d3497cffbc87c397ccee5d01fc2c89ef051324a7061e423720d0a3821a36739797393bdf7a45b5fc600824a17043312bc
|
||||
A = 8e2ba940fc511613e1fa122a9053ed96f339c11f7407938866cc974c11575b3b8a0b7ab2ef456a6d2db6e40073d145c52ad2b706836eeab58d595a0e0c39c6c91de40d0c1bcd6a9e6a630b510ccc1b2ca0f1bf1b3ebb3934140ca50f92d522a253af48272d89b40e2111e88b0f69a848871c0ddb492c3d7ed919d5dab8f6c777
|
||||
B = 63702537a07971e399aa9a1a0795db052d6c8185c79107216babe11d6d8d472b61e604cecf9eaa6d44a2fcdd1ef0b6b52226ea0c6902d929b09e16576e6d1a6921765b2134c5d23c69ed61f36ea9a5552e5819350366240693558fac7a9d09ecd3702076c8c758a4bf6843fa843dfd688bef3f73515db31bfc26
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 6acb23ea695d4b60cce53079390da3cb3a4bc3a6486c238c421f3bf6c93c027a0475f656c3e5435f0211e90458ae81772aa956ef284093020f7b58ccd9373f3fdd39fdf4adb8dd64590f4a7fc05238ba20017bdad07f5f9a6f076b71554a7741bdd8c98ec68f8fee88396cb1f47c64d6da4c228caa3dfc7a9a1c032a9ba4fedc
|
||||
A = 8e2ba940fa9f1c57ccce38642664647812a75f9e54c688d91189eedb1990fafa2cd1fb7554906bf54ac082e5d490e800b2af5c5d3025d5e17214f3dc85905f9625c9fdb98e666b19ff940f1f8c892274c026a99c3b2e86878d459a40a706f3865eaccba6f04fe78d91dc407b8481873487c42f8fbd4a97a1c6fadb821ed06e86
|
||||
B = 8e2ba940f9cdcca65b1572be300153d71cf1f72d9a38ab77d742bbb505e138e1110501f9f7459e46e10c2913bcd189d9795ef2790a669f78c892ff4e8dbda75e86c90a2153b2963338d8575a8c64859ffdadb7069eec250a126f1eff83c0f89283ee408330f5acfbc6e1e0b9f90abb37d11e5d0b07d27670848846bbed6f7851
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 0c012c4d17ea4c95a360218adfc3363f6d89f5aa524aec70049ef94c2c05e59a66ce01e25588e164bf2412f9517b7740de53d037e71ec3a1d426f05b18b128c41a878da75421e8c8ef3ebd5effd40735c00818eeb1ec63182b44e817403c9f1f6c1a0155334be63a3a15109be6d45ac0d1b1ef5cc99e9b284b00c487d91e5472
|
||||
A = 0796fba6276fb7129eef2d1572b305f63d7b8c49371cfb3b2c67b141071e66ccdb5e321fa2c1bcf624c77317e2aa135e1137dfa46a34c3ffefa2fa3e316be81f45614d422bf86fe4518c2fdb7e416bec199de033cb5fef7f193a80c0f0e6ee924a12c8f705f5ed3793ab770914924b45cf2578bdd09c701169f0a881e6
|
||||
B = 12cf934763127284e642ddc232b1c889cd86617307b6ad72a9fe0d48befd7c5c5370a0062dfbde2add256dc0af850813b22320ceeaeed347eb9319bf22320b2fcadeb51c4bb26a160f7459fc172c27a91d367d5a232d00cf7bb778fba83afb744177bf1ddf45446baa035fcd0065f9b493d92eda37e9138f4fecf3ec55
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 3de123bbd50c35805b943e76e97b7e664eb9feb99860750bf97e275029e836217375cc1910c13269ffbd0bd72bb82ca445ccc4b693742a96d19d3dc23f78e5ccbba46d9ff5975f239551c36403ad5fe86997536456c4a5ce54807c24e3b5317b1c7b2a1661aad85b63859d427f0703b460cf72b9acd3f87e2e69d7f8f15e972d
|
||||
A = 1d0433d84f1de082d2058475e0168ceb369013a67aa9417f066c29c28272a0b3f8be5ac7190ab78591ae72a1dc8ce628c683281a9ad563e134387b9258b9c96d2df288fc118a8cff068ee49d635343772c2fcc252facdfc93112358414e1734d6948b909b53e46263e9a0cbffa141ef77bc98e7fae8ae2bd85bd875aa7c1
|
||||
B = 8e2b0626a5045573c013757b969a2f422cbe330fa813135c43734c1834d45c61214a6edbb164530131b81a0db29ff27f8a670a93331bde04c9fc884d805e49456b2b03f111696d5a310c588a0c9b51f2fbf4b248bf1bda761fd061a7a234eb33ca90aced1f6fa567dbcb7f5a7a3b3df1546b0bd5e15a0bb1a051884523853ad8
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 770f0c3104c0f3395fabeb75ddfa2c21a111d23438463941239f7c63e4b6e6832b84508ebf3cde1d90cff0a2801beee05cd5118f9a726a987eb58def6780be899b473ea71c697557ff63a4c6db894e9438595acdd98abfb529d75bdf3c1d619d6165a9edb6aaab8ada50b61a3a84de654706a9aedb7321b0523558e8f18116fd
|
||||
A = 8dcbf983b2c404b826ce3140fa3ad7b7894f577b26d17971cc741a6b9854b853e293878136828beecc7053214fb1596000fb4314712a5e38619ee38ed88068a14baea580080050f16e32c65a5cde87f7a14ce58403385055c3b4837853a77aa23793c8fe14140ba5c424f9707080752a01e4acc1ee916c950afb505015311b4a
|
||||
B = 0552155ef110c126afcb87dd20251220c7a43bd0215ecd22249a21c93583e120ba6f046c6fe03086ef3c97311c4d520110a450470a473d8633e3560d2cb44c25559af07516aff50d6d176e8782c06cd9aadd3354cc695c4ea8dbf85e01dad479c8e8438154351fd5fcc6fc7e9d2162ce2f0179247f756f0b9b34b54be74821c5
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2e9ed66317734668c4c354d720a011fc65bb67439b2ac9203dca65a8f567682be40cbad4f55a83e836f1fc135596b624e4327acb085a61b6398237fef5a6e6560b488d4a673b5ae7d734b896d9647d71087621cc81e94d58e01fc2cc2dc775f9ab1b6031840a672fb715b77bd636e3d87b4949ec7bd60721bec8f9907b7c072f
|
||||
A = 03d2b4ec637124206318b20e6ebe82bbb0b3b90e6fa82a13e95dfa1150f0c42b9d8bbe49a674b18dafa71477336a03f4084338fe670df97f25eff08b4299926c4081e112e5a95f48663108d02906730d5cd798c1055b0c3ddbb001cad8b4e56792d526b6b18d6460a8fd4c52a3f541650332afa575ab73ad0209feb67c071763
|
||||
B = 57e1c76664d6bc3df10a85c7e0ebc9e0f8a40a4a8c2954e648fd657a2caef53233e8375ed863819bfcbc08dc36e72f88af3835c70cc983dd82958aebe3cc85ffa40391e312e6302da870ae0d862f0554df2d4cd18004d983b38f2b5a1235776a35fb1ada3483b406efe006b448a7ccc51af9ac2646d6fd9781e07313b2415242
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 6455ff7c12bf3bc37120fe3f1302a9916a6ffdae6ee6a37fc23ca2f3a7ad910dc0e1027d4dc304a8eb4eccbcf3c87cf52a13dde472c07e2df2420c1d36bdd5e88c3d76e774ccd2ecaf6a0ef55b8c60231b1348a738f812a4fd9d0c158fd5a9fb19cc7cf9f000860d4cb6509271c8e43ae4193843324db02a029beb58ec2955ad
|
||||
A = 5cd8b7c0da2092108c3717a3fd14da2ffceb9f40a1bf944c4016ae338fb17d932d7ba3347c3dd4be4ba1ae79620e68d20a59efe1ff1a2843544109d9a189809ea872a69d31708d2ae9955e8719257dcc293fe9ab3f57cb7329cd26ae5e87c93fa0fdb1a3436d24b547afc66caf029a88cd020344b3210077af84a044548864fa
|
||||
B = 5d99d7a7c2500c33b40676365607fa94efd8edee4bf352346c7269791271acef3edbd04aa15fb909ff20381c49b8c3fc2b56bb57f5066dc4dee5482abf50e57e31ffbc09f7fa837d6c45ab1829710aa0827d8ad38186cd12d4ae931c5367ead9830dbd5a8765963ec0464d6aa6c392ba54d1c3448feda0a5af10e33a9abdcd07
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 64104f6c06e563ec66de4442d35d88117f2535edf9e012897f44daab5a1b8a8696f84db7a68d64ae24a394debb993bf6734c9df542c7e473b2e497396ce39a064789d5d7b339b65766b002a18096e7fb9f312ea5997c2a85463fbd6fc18f25769ac2a2123ccb0e72f14b0608c4c22add72bda138b83f986e78d5c9da31b15b9d
|
||||
A = 832633b728946b3d84faf290c00d9472a8d190fcdab924afaad5e17f6362ba6791e9c1ccdb06d611d3bcf91deab8a59610ecf0c128393ad7d85c01de485fadcb249b7144c628976c7218f5ac4065392ea01da1d68c5ebf91a49bdfc32530b969c4350f76ed7880766ac67dd864da6b6358c1bdd67844b5bc61eb72d38212ac61
|
||||
B = 415e6e6744df0741a8806c80f13bc66fa2dbb15e4df697cb199ca122cfa1b3654bb16db15fe56a750352c41b58e25dd7870cd2f90eed089fe62babb8e39e8448010d861ae606b7d595970dd52a526183a2f8b7bfe761ffb3a32a026c5647e09e83dce75dfe5b697a1d92102f5679b8f337d95b3a69c8305a1fad61dad2737c26
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 11913c40d577f70a5346ff1cfdca492ff52b640eaf257510d311872c8df7ba9756973da5b9206c6e5254bcbbb4bcfdad5fc4594e41ee44e77f168e2d20a4b228480a9908b102dafddd039ba7f7619eed7057e8af3a72ee491a61dd049bd947e5b09a94ef94d5f336945f47104fddb8493ef22fb648ff5376b68e96c0555d74ca
|
||||
A = 08c4b48ed89e8e8dd9cedaea845bc8fe09ab8391134a7300224a9b127e8dd620e0a83600f2d15c449fb64c1f07da51e12521f726caecdff70e928664ea6d2c40f8771d45448479764c12efd179a39def63b887738b2b282cdf8f2cc2845d2d4726abce29d7034ffcdf40cc632386c476cba9ef65b1d8de1711070b9af78271ce
|
||||
B = 23261f6f36e21c2512fbe4e2512e4da39665f8f4060f085a2a86a580f46b4997c961e11919b6e7505d0da61128d86b99c37486c4919de5e2040c845b829b913eeb022ab0170367392a9598b51138ef0c00af91948e4bf08e64a1532278b99877f23c750b7fe6741ac2b48300d7d0234474314fadeb740e1e04a00676fa2922f7
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 42f420adf5c6b32ce53fe23af4e392517e37013b8c3a7d035a93f6ff45142b0b0bd5525cde85f9b7bd9ce219bd3514617e89ef4d9279cb9a3e89e44f1994d72febd23ffbdb0a4f19cb76448199b31c5cc6d7ec1e46fdb67be1211c0ccd93c123d56ac0d9cd2ad11f0c58c713165003495b75b60665047ef80f6a393474cb727f
|
||||
A = 67026f46f89b5ffb44960e3229a4e81e2c5884028ecfb34a329c113b1125a35717740d5fdeaafac5967c4a9928e6497017b0c0b29429d3fb71301eed8b3cafccedddacfd428d4be8910d5b694ebd14c506f1631b45341f2729cbbb2b7caf02b28573be48fc6bf3c8a5835a424ab79a3bf2e62c7c2dd8d9601635bf7a28786c6b
|
||||
B = 6144c9c7a2bdc1d882ca1bcfed3e1ca1e4f89e6678cc04940433d415ca74784cf57b465d1288b18e5ca5924ca769bda3aaa1dd6bfee13f46c985786d2405378f400ab65425267856e54ef4bdb2e91507cdd023517f87a94e349c625ca79e57f6bf025a770a5654039834b96814af80a47d4deae220afc9ae7be470e8986c62ca
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2239459025b257fd0b6659f54b8874f93f07f4d6240f8ad761c9da288cf1537d8bd001eced284bddf78edd611c7f28f1393c6fb879aab6e7df8eefd347d63628b1ae086148f488b01272f67ca19db71a2b284eb17e17aaf1e3e8f23ea253595de474d5cf47c16aecfae360eab7855868b8af361491f6ad96f893f9d3eb66d07d
|
||||
A = 38e10202997872f9eafd13a4382f579a6abd4394e69a7fe34f2e17dc3d855fca8cea470ef550b6c2005b141665f7d054b052f82c7a66b40680e1f0264eaa9f6735847f654b948fdd127d9f3b91fb33aaf7271723af0b51932596e6dda8ff0c5dc45b8a283d3682c6cb554ebe283512b3e086879dae357fcb8364baf75af712e7
|
||||
B = 355a943b90003754968202c6a98a983ced7f66da5a89175e95b6b5ce57d87a8ab31b33d52a1c54dbe7a52ea2ae6ddc91ffee1f498d1e210f243d5336c7f0453553971b962e94a94f1d4358106908c736d929f3c139a26098fe14522427c615a206f4c223d809a93c310387a438d439ecb0b9abf38a32d5246dbd0d6700144144
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 7650985e7c6e5461268867dfa9782cd8154bd6a4bb5857d6555e9d9746ee79b37e44638940bf8d5e974911327f0e53bbcfda0739056bae2248015c35839f35e7e359e93d3a339e7af38c0cb43eac5b41e1406e34cdd4afd458a5d126f70b5d683415b490e0ad61269ffe7ea8972eda6addd447d97e60891e5099ee920e18f233
|
||||
A = 62c18b51ed61c3850fe76d89266e5a947cca047796f29967a6eca0ec23c8b9813709df26c896c6e8defad39527ace9c5efe319d0ac98fc796ce3ef0ee12aaeb13f9bf75490f7a4630332105589ab646aa05c18537820a1806cd5e4fc8abe18fd612fc22f22e0eb1af386d011595fc27529b5c4136c15c1aa5732fa93259742d7
|
||||
B = 89f6646504ad95294658ae769e1a79f7de32ababdf36d0ab67469d0c1a69ffeb3eb251558226153bcbb436a5c1358e9b3e6eb7ee540ccff6ad186b20a2f0ef2c730ef19727f1d33f9ad17353a71d7d46faa385a3bae2c44f7ad6db3ab43ba3ae9c10e9f2f2d911466d823ebd4317328c904dc464864fdf563a8445409d53ecee
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 35d48c3e43070a10dac0e256afb83b219aacc0036f554bd998b9092ce3bf87bb5d3b00947f2c86fd4e7ab830502d15fb2d4e47ead087f5c779a9ba56e272ea86116e2c81345d379dda6b581e9c8f4df8ea56c78f04d4f7412d245e00ac645847af6ae97d5d2ab27e48cc878d8b510c2dc753f6ceb1b9e7bdd923e0e065a6c11e
|
||||
A = 179be517743dcd4e06e8f7a217f2a4726c8b3461c0c1da9fc0f2c96b924c1d588d3e54b1b0c970b3851b1dceeee6089247a28f029eedc3959b4b1aefa44e2c3fe370ffb4542523e65629cbd07190dbde3c5a8ed4e45c07143d06ce880fb15d0b1439714ea48271a8cfdddefcba01eb9f1cb4fb825577363c19be4a0c6cb1c2d0
|
||||
B = 1c46d2fc55b249973d2dc30d0385423f987999980e528b1918c8d080a59f2790a59e21cc855a76ba6438071c9f6204836666aec5888cd32ceb765263b37919a6b34bc3b1da853ab8955468aecc5c09997777f34ff82453538488523a420824e3835d87b2cd631d07262f436e808ddc64579dc452afbaead9e5b068363c1d9d72
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 445039f359b55eec647296fbff4f22beac09cad32cae79c13d591e314fafc2b77839816aa4f641250938865b0a2c30a10e23da71a6dff5985ebf3df4429fe64c327557b12d987ad9e9971f7c7b1e4ad01c94e1e5322dbcbc4707a959a401624619029558fd6f5b14564469b13146f9a2555916491e4d77caa70f51716b299135
|
||||
A = 452129b508a60de52c82622985b9bfa12b5a4a91604017b675fde339a1527389dea5c126ce6d8a18a84bef68e10d9944ca9fab4f7e305ec20fe70397539c3f0b75048d4ec45445fd081341d6e7483a4993e0a20a74f10727f89f326edb3884544a87e6d4860ef23b3f9619f0fc24a6f2aebd0aef503aeda46faaedd5d847d703
|
||||
B = 39cea0a78df8bdc3413fc2cff3d15d81e33ce494fa2ae94ece6969bd9a0658fcc687b1e5c31d10ac484791152fc012a59b954eaca0ce6da84b69475753308864299350f52bd65f8e50f2076794163e01195b94daba7f6a2a8f0a60ae49e46ae2c949f62a1cb78d49a1006f0efcc51ae81b0f1566b50b5363025ffa795af9d1b3
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 6727c0d0ecb4a375d0fd1bc52146da1242099d445ed9e87b1fad4daf8369fbeeec49027d88bd98efb425c1e3f73e412fb327680068ae57d4a53992f3759af0ac1b96a92f56c2cf552e6682d1fa90c3910bbc5c0b1754862ee13c5ebd62d5b98bfe8dbbf9bf53bf9ed0b967f3c9da24d4334b9f3f75314b429b05b8e27142623c
|
||||
A = 0f4eea56b810bd1a0869d3cad0bb3dc823f9ae47d81a1cfb8e872bab2c1cdc49cfcc5f6b970ef7762c1f8803e469b1cd772909f5c3f0c1f342cef54b47cd7bcaa19c0d15d98cbde8f596a0c5e27c04136b581b351dd855f1c8e04216027a454933d0f5de0f43a1a758e696856d2929eaf02c281617e05fb3f41e1da33fb54a7b
|
||||
B = 785a1e5aedc264203f899ff52bf6a1ccda3b9ac6ea29ab867bf2af9605ea088f5de20e172f3b5b2a3d1de676ab203ffaf07c45f32dd82df33b080647b3d7c0fed9b66d24f4a5af1369d63718e896443749f55f9fdd2f5d9008185b086022f5cc65150f2e9d8462234c5ef57118c2b92cec80efb2a853123c157a34ec2363a188
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 6e9947beae4d934253e481d27e854a59c4047eeee4fdc7df7e174a8f045776109c148ba3721685195b8fb59263def88891c5953b5a0ae85fcdbf02abc76f4d3c0f5d9496327d063ce8b3ba875b4f119dcd8beefb3ac884c25955af61c35a69d0670c3c349564e5b84f7df4252d6d3b29d9a75f09e9ef79f0fa9f797bf75b8ccb
|
||||
A = 4493bb04deffc492cf31f39878767cc29e3b7421904a730e1345a6280d600c2f90e298fa5ca14da726579413b520c26a1b98eafb05f7c9cbf0191254837cee14f1d28d8f16d099792430e4a89636006cee4b26e5bcebaed25bb7f12f3e409218775dd7b91b5f4f18f6173035cdf8c040115af4f1a539f684c33e6491e331c1c6
|
||||
B = 0f31d7128ca48d0ccfb0b44d8dcb492b26278863797bec9d705e90274a01fceeeb94f2d87ebd1be1e27766d50d3ccdb489bd7ff37209bbe8a553aefc6ee6064439d56ae12b0b3309c29216aa5620f81482d452a42175b466e123dd33b8f0e6c287fb4a05c346f261598c2d1a596ec2b6b6d6868a8803ba311f91fda60577cc47
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 3f4a8d90017dbe8e77205e65fa7a0875a1ace6f3f215c2974e47dbac779804143da3dbce92db391c2614c078997c7d1a15439ffb51a5787f5bbaf98a4dcef576a6317b9b92dd8141a8fadc05d3be7c150630668e620a4e07b4b00519f34e422610a160de112f1ab8adf09a9169ba95b60242c89196ac6e155021dd84b3054511
|
||||
A = 07aa39d8bbbecb27551eedfc95fcb4d2e16a546b9370714638a57d0a0aae7b828ee7f406c53719c1aceb08f24420fff3c48c5c3ad55ac58b8d771b26d46208f0f2ca4b9a529592e77e72a79d245c0df66b4eb98db345719104b1bb402171a76c31ec6c1fb4a89a1ddbdc0cdfdf63ec1668a6aa67d4f059ebbfffd34d81733955
|
||||
B = 3fb86ebc3d9871c0ee555c8b58171f5b902890cddfd56af10363ab6501f905ff71b956a8fe05a5aab30e754985cf89e0b57b584b19baaf13de6033b90de7e981a5c0481e5395c722574ad38710a09467c78a4af758314ace4b916b66b77254d5cf3651c604e2db74d52a7f7d6a0d6330521130a7d3d3f4abf1188ca05a94c625
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 8a7f3cde3230af1f1fc25e0c0e9ebeb69161d3864fa5a03e5d7f8c82d9940ded285df35c008f61cc151b4578e2677b2f2cff3236935de5bb1d113597eee448496fe29bb18343687f6e9f1c783863e949a0954de2993d47a03607423b458bfd18c844ab57e9e2a43930df159ce8564edb5a2a37a06425626502e3ff9363b73c79
|
||||
A = 4f61db5497413668948f9dca639fa0b8c309827d09ba1bee51c9b9cb6e2505e1080e9f37b7ced0429108d2865be341d28a8dc113d2fb0c54701ba26b447537fc4ae4e9b663e431c21114edb04bfe80ca5ac6c8ae544db2a03cb886a47cc3d02895c12e358501e4bc0b78f11dd0a9e0b5cbeb93ca26af464a4f941a04d96caa43
|
||||
B = 07012f2a22b4feed36e3c42564d8e522d636854fd67d0cee672752a49d7d662d3a402c462b44e55d4cc9f528e8ecf5192d823606ea064ecb07cbeff7f3f8981f0c98d6936f78b856e55087fdc349c41f178732c63c86441a9e50f7540a200ac5ef0bc456818ea6bce8449493f78376247a6ac5ceeb987ca6d593b042970500cb
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 76f8b44df8d8547f8b3d8537393d2805c699eb37d19bd115bd5539adb6b6a00d004def3b7793d5c71e0ccd2b7e9fb87103c1a5f56a8f18ede1bfe1607a346297166596aa78dc584c7c32832e11b72fb4f2d40ae1591f341919bc0157080ee8febb7fee5461a918d2178fa407c37a8243e24206ce2c19c3addcc2b7c3c1912b6e
|
||||
A = 7d77c556f07bf2a064615d8fb92797ef10a47ee09b6a0570bab9c0a75f6c974af941c0616a3dfde8207b2e5e521b1ce0d3df0d472b2fc2525afc382ead0fbbc93b4b3e94ee5092fc803ce3044a4177023c44f1ad593610f6738471543d9038915786abf1e80b3f88245f1fbd28c7c9831a99a286f63feccbd4cea9cd35998be9
|
||||
B = 0edf46c2f7d7ca2c0104347292bb7c2593b3e2fa771407925d2390564d3002b11092b735c0df368eed29b09c0b173d1d438a0f80c53311751c0c0e8fb489dcf6ec9113ec9598027fba1d7512d00d3c6819095e654f530e58f7e290b6fc6d08e383a6d6eb72c9e1bfc7da13cc9329568357207f127db545de6283682a81aef02f
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 0f580f9d2438b22700c3ebb23d1dc296f3d33deae2d32dea51c7ed3a0ce7b06af11046bc1cc279bb744bc31e7f822c17ffcc5dcbbdabe213bf97bb85c7e19ee71a513bf59b25b3b5787e42e9f3ef6aa1acb8705d69924a107b4f88e0cf9276c2c7c47fa4bf56c4900b557aa5587418f0ddd899630ad3ff678b5b907c07247b2b
|
||||
A = 559a8425772b6bae495d89502ec0b0f612ce05901a75f5b123b9b739e83ba7288bf50d9f1d60a35e0231bd55415eb627547811f9e1d116fd42fbe05b55ecc65580df3274f04216e5b8112fe355c616eedab5b884df886f8a68268665779d317e8106a91965df837fa7cd8e243d86ea8735250ff6e52e9dbca9eb4fc081367218
|
||||
B = 27d368393d97aa7053f13fd6d289c8dc75e95ed80902023fd4bc5d451dc9f6f80a1c9c9093764c7fa8712834bc57ee79146332ffec2f99b4f53ac916c4fc42cd19c6bde275bb6a1086ae30ea83782728383dcab31727182fb6e3f080309b5e2b64681c57b0b94d9b22f6f6f7de7f1c0f6a41d15506ee0a180d4ffff0a41b3d80
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 0be05efeee19cc91e30a9277a6551aaea63aa3861b63f6061efbb0b92296e09f4709529eb849d9f40406fc59c526a4697144cef9661b556040458940ffd6a87ed56cb073d2ee0e6d1f05936fddd1b9a8974a3088577847ddde6bbdfb3d69158d5b3899c13ec78fb5cb6aa7204efe308bbe0b52f18381fe838536707a8a27ba0d
|
||||
A = 2c8d9eb4e2a58670184fb9c00ffa47029868b84ac0142f439a79e45f81440d56961f9a141d7c93ec675cc8f919ea78c94a811521c96275e3c37ea3b0802464243f6ef8ad4bc80592d260ed1db89d1943148eb3fc7af6b8637502a39bd1a0f96abfb0b8bdf190a4219b316df401fd89b6cd62a005168e9bbbe4ee212aaf6d6597
|
||||
B = 0b62c2b93aa90eaf11bdec69c71db10c98634b260bc38ba8b99f5196163eaab0ebe5f5d8a8b270ff0da4ff4d1455230db7b10a3c91b4112d7cbd9d7e9a11978764524769956e869d4c74085ad7db55b519cabc90d3b8ceebe16b6f79ca4cff4372eb4785075f850fa0b39d187bf78470bebab071130ee81b84a4b2d428cd09d6
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 705bf20b7d92e68a69019cfd721b27373c7ff22f911066907f556321371fba70dbcb9774d3a26ca43e44ab20c586a3c1546fc3152ce011be66e04a59c6631bc8bde18efb7bf1743b9ed75a7a6c5bf5a4117368b81b112a3cd4e1c44a621f534a11c426451ea5fde880939ee5bb28d9843730e284520a976cd9f60c94751050ec
|
||||
A = 80f8ccda42d67c71e2b300cf66dd8004796910249f21b2dae58fe8a2dd397c2e097eeb590095b7441fd99c2f8be6782dd31d1278bf2dc04cdee056591084ce99750b1c00f8adb53790cedc30304243bc6f745df5063fae339b17d47ddfb5acc84371e1788e589627c30c90d03f1cb83ed6c2b318f14ae7ea362531e19ff73834
|
||||
B = 2949c6fee310778299a7239f3972d7901a434328400440bf455c59ac1befb910af7e66460467880b85566e6645b284c0ff489f81c93fc4bb09384c294fe0a5bc9dca8d471aa5e3af2d59895fe80471171c294fa3033789bb171b7e9c5d6f4d402babce5a598b516c64669cb66440b5757022b40a27a1aa5ece6c3e496287c8ec
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 7306e3172929c00c29ca1db360eb4ce82066f237e9cf6aae368d1f531620e9b61eb64f5b3e2b735a3b565587d7e955d052df94a20e4aaabe493dba2c18e85fcfb65df166cc48733632d165129b112598bf5e4c58dff662e558e5f71b25f36708d3ab6536b1cbdb5aa2ee56d9e019a9c3629185b188af909831629ffceab634fc
|
||||
A = 5cbde68abeff0a10330ffd04371c3dfc3027a2388812cb2b5586927d200ef3a4571960ba68b4fd8afdaee122424dc12f411d3d199537692e4cbccfb87fda40a50fcc2928e5bae460f10752119f46041e3377ca072f28a994826e459a5081fb923011ca94dbc635e4d16c144731ab0a90be090d3425ce59fd48f2bc73e3d56b45
|
||||
B = 3d680b0583f51341126fc355c7f65186b77e9a239eee80ea88e397612d1bf8e8f50ad7175b27fb7dceb6d93ac46efb41154b2fea43118261fa7ded03e72e48a6f20610cf7adeaa308cbb987576de3d7f0bf7f8d6836d62eaa36c59fc7defdbe23cf9687038c3f2108581ed86c0071fd67d36082a7d50de10ba891830cee92171
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 361ce44d153f4d251952c0b90681a19b7d2d8df7a6c5d459691a80c06107b2e818f93f30f8dad352d2dd87b01530d51fd1c67cede9b1a6167697098e41bdc5dc5e7a3c310116aed0c7b5fd99dfcdb3517c13daaba6ad10879f600eab846cdc110d392d9bdc0e8ab34b317840a725a7a12ceb48c75e8dfeffe2947aa85b2a5158
|
||||
A = 0cd89a84f0db9a32187b94818f89a93f19ce1f85181b88b2d657fed5e4fa85403a59f05a2e8fdbf4db8147c5d4a2b8ac33558a1195b51bc7460cdc6f393c4136235a1d4bd14edf4fdc74f4224ae57334e28c45cd7fa5abfee294a4b9d3d86c2b1cf1ce6211447e15d15102fbb95d16c812f583af13b7244da2a72147e0f7b3b1
|
||||
B = 2739adb776f387626bf0e1534d5f0ca0947d633d357af4238c906cb097acd033a224f12bad014827985a976dc93ec8ce625e62ed3e035295e0f50f757f52e1f00f240c3f422d319495921c590902e9f15a57731d3810b7e319d57b18d99be2750af6b475e1b8ed2d788a2dcae1736dbbb66c97f61502b8721a38c4e0c0081151
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 3aeb3ff6e797d271fd2271499a740a91569f300d7392a7b5898084012a3c5ad379a57d5169e43089cd58fc7210314758d5368dabca2f0ec5cf6786801bc99b45cd60403c732d9f98936aed76da724bd3e7d4b622dc690778f11fb0310fd4cd980b220627f7a864e107f93a6259081c6581e5dddba4890508af8057c1af29a745
|
||||
A = 3c01ac611a38dd8753dc7f9412d7cfaafc28e0f8f3259c692570d9340e443bde62045ce708f12931c365df1a63100c51279ffaf5eb9cd5fbe4a0d5e9d361978590541c4136aa0102d83eb3fba92c6b4b7b56fbd7161628aeebbbb6317a99f4752f13ab189b944f4423706ec58dbc4f3b601905f5125fdb82e8d5ab32c01cca44
|
||||
B = 87dd023be26dfda2cf0f97f7643feb6e066afb10e143e4497ecd813a4403cef4f00dab4c4fb45d6e2f7d11e43159b2791598acacd3accf342603409ca0a8a5b6a9d7e95e08d6af4e08fc438ce60ad022ca042e49940141f83db841b6f9386fd4aae6139e921d45f11f8b0e55fad6736d77f6d0805d4b77bd7eff96121f489d0c
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 734a429c91f5b0f06fd47725ded06222c0193dd407e9daf136696f203e153c9bf6df59016849284cef93fbd35edef2cd31c9b956fbe562d2a22100f177254144718ac7d22c99783fd523b642984794bd7beb0d0b363e28d3f3469ee332ee364faaafef25c1d4a11b5e517e44a412ba717a113ea9e1e8f2d6db8fad6f10d06950
|
||||
A = 1905086d5baeb48978c09bef95673d3164a6593338c921cb80436fb6cf623a7692de245ecaf0b77621441a81478c08b833110c2e8ed60d2e386977e14815a79c78d6238f952c26cede7d30601411b23e337f12e9dcb38754072bc2780dc083ef234e3e41efd91e77e9467d901b1818d718dfaf29ee1ef758a41d74fcd96f1382
|
||||
B = 6e52f31eb94cd75b1a5985454f87b07d2449479299c9767d0b2e8e91b183027d2eaff0039b60de6be980a2556197a1e5e268f3149041690d47e93ad82ee48802ee045f455cf35b265e0268e905defc63df179a11d6d28e0451eccf24a478b2a696e17d5ee2cc194b2805d3ef25318a0401dc6662ecf43822f31916947e0a1da8
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 427609751f28edb62c717bd98ddf999cfcf65128b652be1b5aac0dfe1bc0f7687c580ec70c8290455a9448c69dcb550c0cfdd109af561ece2ec8707c1d02e8097e780f32ddd932e706f81f68711acda0e7610f4dd0fd55f6ac7ca3a3184f655b0b29d2d62974739b43ded96b413b9e3f0033ca1edace24b6bb610bf06b5d940a
|
||||
A = 39f9d6a8602f69d9caa78a6680e86232afb933f8087bfee6197706aaad1b5d986e01a23ab0e68a5d48615f3e95d1cdf3bedea4a36e9404b55061b11c7595e550e871dabeeb2f77aec6db0c62d1d1f4b1541c65d5fdf54d309e1f1b419f98ad657a9bf12de0204243887de1efbb3283c3db069ad3288be1c31b6bd8261f1f7f90
|
||||
B = 3bb5fef79b7f3c7a1abc9854fa661a55418659771168f02ce505255619658517385147e32abdbd4b1570320041deb73fd3756c46bacb4ce19eef7d6620fa20947e5d7e4fb97a90d1d9ada857b55a1775fe1a51a8744ba504f562930f116623b0e01bc264a292c0215cb6e4f1709e952e9e37bd2c22243eb218fef8ad1e277dfd
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 533d6d8d7384e6e65569ba0daae0a8cffbec1d20e417a6edb42d401a59de0a91a7e6854db081ce33b76faa63f6d866993c245e69ddbe6c86d339f7107a4807856cbca23cee2bf5496388ae8fd8d7c78767d0775acd7bd6202dd75451b424034e2766185969b5663b638d539f718e50a9f752f406c224c000bf1ae1fdd60a2a82
|
||||
A = 7d8a8c8f86383c51df46aae55a1b2125db3fd05a10113b977bf8c6c217d558501a50cbdd66a7faa6d3869f760d39f5f83eca0d2b550843819c716c69b9ba5c80c171d8a5e2f6445d53d1dfc0775d28b26b78175e27571af7643d45495806a890a8ac24a7749b6c2869ccf2641d2dc51d3a2a2400b4b94870c8b34934c8f0260d
|
||||
B = 151f9170ef6b8731f80be191eeef40887a11a9614a370aaec248e37dd1e281662d2f36b6fb9980feb42f7946079b6255134033be7e5a63737c0c2f035aefab18af0ae0f00f597c1ba60d2c1a77dcc33cd660934c3640b0bbd31239fbb9f3a7ec0fb3385c70582bf75bce7ce4f35c3f59429b5ac8759cbbc091d7e17aa10cc905
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 33960d7ceac73f342d46275e04fed56563decf2fa4c0e9307c90288e911ac8782f8e1354fb051a9da8e2db83d7c710b5d2b611495e72ed42259ce783a7e7a8f601c07061ec749481d39a082f29dda1f9c7f444a33ae1c1055d37a677b848af371cd3bd41c851d31a07e144d7add66df39576b8200a8b918201630b3da8e664c3
|
||||
A = 063815fc3637712e3dbccc140f837a689488bc3585f8df9b5f6dddc6379f65b9029b5e5fe228c257575001b257e4612bb3c3884ac0ec5e9b40b1ff9024022e55f49c9ee2519681d4d9969e97f78418555bdad61db7d99784227774d06769a906584bbaa02d8c4adde53c37cb2c9c63a4390f39f87e76606a5f889446586b5214
|
||||
B = 61a95ac8d7450c1e84c4f878cf578a36a75f9eacbb2fa19ffb6452bfa8b326a703f48e09cf56f95f67cce9d5df6813be4d29c9021111a3c30d8454494a3d4e89302bc1912ad9de486066059bd0374e55edbb5ef90f380d799b4ab5ed0d57bcbbda3741aad1b3bb7702891ba4deb2ef2c76f2e9603331565a96b085f2aefc05ff
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 3a1ea3fccd6f336e6d444d68af1753b83145131954c20f1e3c433a89eeb7e267425a34d91f67fd65191dce85769ece2fc7ab12d032f3e30f8509095ecc05148e47a85391b21a18257c338a6a3ca9816987abc8143fe443342b34afd8a52fff00dda2e42b1b39322bd38c6a1f711051f791d6cad2a47ebd423a9b933485fd5861
|
||||
A = 8cd0fd6e7d3c80dd431bcaea37c32a7f49af6fe2b5cb40b3b7b137971e321b7fed8c83a9e3288882509f0c862389c5d8af892b799613f621fc03470d8a0505156933f7dc3b2b813a813892067371499a316e63bd9f94681b18ef35ec046c2f430e54d239fb4ae3daf110c1654da8142e9ddc0f9f3a6c98a1d46cef2f259e8ccb
|
||||
B = 73123b70cf137a3c0d3bbff4d81547dd884bbe6309234be5d7185a8a3de97172b7e302237d0b8300cfde75957ec4225b2cc3264cbd73125c172cad54bd0f99b327a98761ae4d15521323f14a3727bdcce3da113ea2f26089bb4c775eb540c4527da96531330db60fe72db6a4a43f7d4ceb21a06d2f73652c5a23bcdc89056029
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 4331f18a94c169cf0253136bc4eb7480c9fa4401c18db1194371dd53e5f7b75f07ec2e1e1c4116a5d2a8b2cded4b22925b67a88af9b8479c6e821d58cec7ed9f780a4c41e729982cb33f69b87d01c11cb9a8f7952db1920b6eb2124fd5d820555a99327117d7e8e26d18e748fea3ebc17e1d07161fda57a21a70c7f4e251612c
|
||||
A = 167c0966a64416255c97f30185c67f3b1c39b4e1cec80da6fcecbd56639590ef0916121df9d8b872be7365d78db36b7d995d7a422340355c03c5b8e8c735422bc5fac038434c56ab278995fb206b8b01e95580d95de6ae87b4fa885eca58f86dddef351aacc9832b87daea0d29ea8f75c414980c354516302b64030ceb2a58c0
|
||||
B = 75a596c8c1d90226fdbdd0872ab3f6f68dd2614465790bd318141844000fb78d01c4de3edde912256298aa806bf076bae134d2bb46954aa7b11ecba23ee42adf0c49b19eccd4a37c919d5424b7ab7148a8d5a16d429d409903e399ae078b4c6854c872caa949d2118e5aac44c58dddf88da3e613b92d1a93f92ce658f9eb5aca
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2468cdb1a26eaee34db3d2724e37f023c8a1788526b3dca99321b574685cc8303c609c85401a58fe6da181daf4111fe8c6d4b7428b1cd301cdb9bf8cb6f33140756c8b490d3b2e538ff294fd6471c4d17b9d9e4adeae0df088cb9daee18e825a368be57af4a096056b9e76b94c8d3b911b6a074ed41082926773a585007752ce
|
||||
A = 1dba6d3450c6aeaf768b5f22560d53808be49609dd7909e3291a684326ab94108d019735883d7b2e2746a1349376084d362d9fcd233eae998c4c4e1298e040e7195e4eb18c0e8235482e9df34fb7ead4d97e07ed298cbb6dc1f6cd9b43ac0a3c4bb5602f72d1cf4ec969200e541da69f29055959afbf09568b5f058eb00f5b71
|
||||
B = 1256752129bc0749fbf301a7515b7da2b3b02e4867ea38ffb8d182102a0560de5afd088820faa5fabfa891ebf81646476e914faeb94ffc0f1b8857ba737b03004c49726f098adf08fdc079926ad127b04f9cfd108b85dce48985491668a8fdcff33e73c09ed7ead2b10e3ffd7e3018771f48f5dfaab6cd613eeeb00db9e2c5fd
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2909d3aef7a21244efc9b5b16626e260907ac11f3d00647f2170ba37197e47b9767030195c2f6d5eda717a83a152141bffed2e26777417ecd8e27aed8666698c2e85a414dddd52b07b52b0da7e08b3217fa6a331f84820d21086a4424974e1e8cfed3501eb054242a9f8bf0803a94981b7b81776eca6d07cd50c050dddf81d68
|
||||
A = 1fe3344276193338b148d24a283da1232a79e3c4511c515cbc656d51765639791d33149435ddd0203b022ad6792da6db6d747fbab3b8f621e396f270a8cea2ceae20d2fe35075f26899665a530aa885120dee3ad0ceae78fc90a4ab8b24768bad013a3583cabf5f887d32eb9d7b653869e8f1d02e64d007fd2bb3a1ddf1dc0ab
|
||||
B = 771b74a9409159b2390b2e2356fa4d234e010703634c41a0aaa3c0bf1f86aeaddb225f6f1c00ef02022ef365e6893060927502aacc1764c742939e52bd0713708c9f537b9377fe6fdedba1c7b6932fd5d9554d4e4728cde31311fe4a597f6855a134c805a1a61491e9413ef6aa639e0943a8d03a6f4a04ba23ca83133322d581
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 22407e4fe280ff5a10eaf46d8e1f5a1e77a07410cba4106466d703b11764c60124fa355733b47327e952a12869476306926cabbd797fc80b4a6dedfbec0b7718ee754d447825cc405a98b85f1e09ebb9294c4a4636aebfc61af4545b921cbe759d3f389beece3f29c2c7c07691a4c46a1a72ce418a239fdec80df48732627866
|
||||
A = 7a2d6098d57699d749c4586436bc7f4a2a1813c5584e315cfd268ed87e1798f5e86297e0c35e5ec7e2923613325831d10a8f38c64a48d9a21c15736ec3b32dbd9a2dd6c6e8aeba8280ce7d13d0ec83335ac6e4b7949973f711dff25d8a206db602368fdea2fa68d5b29f8bcd923462bff0bad141ebea067d64168b81586efb27
|
||||
B = 44b1244138b185fe57267e68dc127801b7772d9c98cb9edad0103a7f9278407b8a6278a72084eb0df065019678e53e55a47591ef4871272b5a55eb643a300ae080bedec742dc8fca1cce92b54113c19cb5feab2801f26f87694de2351e056260716671771f843c67bc60398ae66631e0658a892fd408b955aa9467e89255fd7e
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 385ba217033463cd9cb882fe30373c2d8e8475dee54aba1ca9713a709f40844905c2544ad792784cc8eafbb412dd68de6f98522dfca1c3de8e3bf4cbd09bee4656c4341153b17c98f9ac09411d16ec9880835cae772bdd8eee51eaba7c02ca6a1034c2c5d2d48e7ae3eb0e22f59bf69537ab6f1e49e58a71c64b8934113eb069
|
||||
A = 7d3ffacbc5b44ef4e8b876bda0aaf996ce8468a2bc9c90eea56ad07b459667b226c7f4913e8a26c76d7897e8416728255bedca9d3699342e542424b6ab31247015b87aa73caf13762ff7f4982e9d5ec47a731aeb5237bd0007ccdec785ab3d36893b3fe95222bdc80027ac067d92e1e0c2528e29856287704a767a83e9e8a10b
|
||||
B = 2db682f1ed91a8f6aab4711a43374f7ddce626e2203844943923327a75560b9358caf635a6a0367a871adb52cf1d69d2ac16e029f1386eb24e69662a3211498c13134007f53b24e8cc19dc8579187a44f71c39692ddb63c97db6b495f2a477874556f598de1654addf4d2acc640925e8d6dcb0cf8aa505ea94bc6d32c68b6ffe
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 7865f718cb30026837ca006f5cd997c5b917726ac6d9bd8c3fb9eabda0854d528d6cfc10e4cd3f93f6848582690c6a83955072daefc6959d33192fcf42a111650e50776ba9ae43d3d26e0ef2c6b60c3871aec33eda8c56353903e7ae96592fbf350b88d2f56e03f7f327022a2aa9b7c484a000135b85bbaba6f8836cbfc81901
|
||||
A = 7c2990afcd18e3caa1fd69d3d34012df8f224b31834c6caa18fe955c9358aa1e5baa5d5e55fd8575e8b4842d0ebe1d085f5d0b265d85e1c410fb56250e5bbb53ea1c877a01508199960da3baeccbd789bc18cec6f5e11468429131d4ce6ba21ed1d3282acc79f1c712c9e100701649076c6619ce63687a584999be1fc36c637a
|
||||
B = 2da8f89ea6ed4852352fa7134218a60afe222a13350865dcc5386fa0dbddb31104447d85e747d4e03c14249b914ee0e33810c26a0c9642412cfc87b7bca63cc5474ce3a080a9944a9ecb01687d47c2007e3304ceec2d2c3fb62288d707f12c36a2a3a4d7d4788d5e02e7e6933484fcd0a13ea34ddbbbc23c43c987b29e6a6566
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2d3dfd14e7ec60f842d1db83e29a0f6b052990fe8900887dc44476ed3948870c57e72e91e1941c476baa6aa86f76dd8ab6e6ea41707242c46d39b54215bebdb1f28e59d719fde18bea9994610214ea68ad9f2da24e1ad8a06f8bc698f8e76379ff332a2745af472d52a4b8e57d60280e19f93d5be669e0832824321e9ad8e76b
|
||||
A = 7acf033f16023d08fd1ce59bf509b356780e3a3f67d8e51d113acd842a2e631f78939c7ccfb759c2c23d1f6551df12a37152d310ea3c87944000d693b80a8348d4e2d8deb20afa2b680d60d175885793a356909e9f30c0fbb86416387b6fccd5c283ab24c2f25975d03f4f63ead50677d4f36d4abc6a587e24f4f84f5a479d40
|
||||
B = 8d9fed484222a3b0feae346149e97d6d426484a23109dedf713f796f2ac4869c48052619a0c6dd93f83a2000ad2e17ba5d07b03499f780795777b60e8a6e029b4192cd951aeb96110c2e7f9b222e222ea1b3b0f6915ce082cf89bc9eda3b093a6d6e6073558d639e36b338d39ee1071aea397af849776ddfd3b0fbae1bd22c7e
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 3f66970f600a9d09d73fd1ff813e977f539d69fe1784b8a2f99506d868418e4b47338ee0cbceed555f88824f98ffed39befb69e8907a5822ef7cd2a9950a070aec8fe4db9d68e1c0620f9eab4ab529c7e69466e325fe1c6c011bf7ab62bfd1a136597d7d5c47e8eb161ea048477bedc88fa30e4f7ddab2cfeec3fd0bb3fb61a3
|
||||
A = 5fa80de456bbca574fa714911b9ca94af1173eb72b070c02ef2d9d309bc9a2280da161737520d188f7773713b49609d0f464b7f9ee4e6f543d7b4afe587f5528e48dfc5d0f57e2f80854d19b1a79014d7810307738f8ee9c95ebd7a14f57dabd1a65306ad9490402cd5197b4b875edb11c7a8c8a2d84ff18c90374986736ae30
|
||||
B = 2b8d6d657673207af8dc9736ae4403cbe18cf5a7342db3a642cd64cfee3c7169626d964a11f0d729f50bf4f1d168ddd25925122513f212b22d469246a5d29139dca4b672c05f5f0fbba8f3ebb155b50827222509fac81a29569d3afb54637a23521297424b038c7d494cd17f034cb3f4391618f9be7b83ef9eb0b9291204cd8f
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 54e95e86e87bc220c8f53f8485402327885be34e34063a1b81e52a23fc3056758cea1c039ac4e513f70ed9d394f5806fb771dca8e342368184e674e6296b9a705c6380bdaf11550cffc73f9f55b9385c85fb648f105f11138a3e1f9dc0a39a0f9755f8328701484d45784e3e4b2ebddb32c9d9132867c6513201116428b791cf
|
||||
A = 0b173f5024117f01e232da94030550f07a8238d9bf01f724556b8c9f2b9844eca40739099b26dd07d8e7f987cc990c4219fd6b85928caa5ad34ceb345768a3edce117ae13f8c24a0fb1bdc7a447f17a545801518e4672699461b90b49fd063d1e9a9282b92a145df17abfab8984a08b12cf99fc89669b84672f2541860fdce26
|
||||
B = 63ccb7ff8fb3f8b0b81d40ca99315bfd75a59b7094b349bab7964707e13d45c5adaca7384f9528e327bd7e581ee626e99afb854ca310bc712f63cd54071d22944a20d722bfa2dee0b1df774b36fcb22e383120122e34d1cf03d89e61ce08d1a2b3429926a6485450c810edfa32e93b798d1d21b2837de2dda41ce43ea92b9f6b
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 6e0160eaac8e1c31cd3cb6c5fb91ba086d033b4b69e41dfffce7569e61770f6629f23e12f0074c47c46653bbba94701ca798e1a242f7c4e25708d3acb5af6ea307b95cfa220f8879cb4cfff96b843d6eeed2b15c8f1bb21bb2b511cefbad0618d49d9ba33cade6da6ab3b846a6a24e35fb36d41201d3b85be831522b9bf509e0
|
||||
A = 0a1b0cde1403c856bf5060fb62659d4d77168dbdd0555e143f913e4e3e59a85c2f5acb33183efe10451011bf55b5349b580cc4c77b0c2e4e43c3701a47ed77861bdd1cfc72815648f9e4cebd0ff5de14569c9e2fb4f28fe5353b6c02c29e5d59cdd85ffb4d7b00cc838fe94efddbb0add5961eec10a305d8717c746640779cd0
|
||||
B = 4adb59a7382dd54a507e5c43540edf84b787096c678eebcbd518b92bd18201bbe08bee538061036df61e7b776d719bded24abb5d9da435d9c5a6d65a8adf98298ac1940e92f92ce8c998858860efeb80e094ab12cbb762d1c08ab67dc417d52cf875f111bd296a5c116fa622a8d55c46791022f3e6c232b351be54509c472450
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 8dd91f390c1f85f153f332de17e5de82979755d835398cdf3dbda1ee73c68f8e7565a964ae33fd5b1f1060572bb3af67eec79c4c3e2eb4de118d471f74351b80a5dcafc682bc3cfde642e611ac1d5bc2c49b308c30985b1161c4d78cf7621b503e2dfaceed886befc004f3a729b4a9bcbb8f13791d973bf38fb8101d6b7a4d4d
|
||||
A = 842b8a197700ac4ae9ced798cae3568d338559d8d3f26f413efe95ebc71217d5d2d5a7a8bfc9cfda8f9df82aec12dd16b8ea1ec87f32445e4e69965399894c5c3eedbbf5125fc105f43987d88a9635047918cdd8fcaa66cce9b8feacbdb378894f80eebd9854cd0f8fee40977b0a460cd3d6de2913d3cd5c4b18f9b0d20fcf35
|
||||
B = 76c704cc65ddbe15e475a9d2010cb4830ebdfbe0db44e2b1c8238c1e01c3dde1f7efeb872b1d3b248c1c60d2be99f998b07d4fa31766764e020f02582c6740163d1d4f65351415cd0d5f51b4777c9c3e7c53691043e4fce0f70347940723ea5ed38a0ba978dc6c9010c0c16a64175346b619fa523927bf5b0a3a96e489f1322d
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2b591d2c57f6a5484b43cd7ca247c48a1b38319e843257331c8807d499c7763de4eefed529e70d4c144e5e843ac00ee8d106d0d82163cfb7afe528a7daad8e7ed105942d1128a67e38d59325cffc0c3dab9185247e0082e3ccca82a900d917c9bd0f892d4b518a752f8e9d38eab2acaf3b3b59f15b0fe4cb9a3dabe6e0191493
|
||||
A = 4d424d97df47db6bdf0f0ce58e0fc09db1455b7aeed444c9e099a344a8622cba9f20efd478bd1f542ba7a33bb7da8460f0b6b0489b410865e879a490df70bb417db6f0646761dfa1898a032372e06c15cbe34d176567f2e4f921733a8190603dbd6d3dab47de0b14031d98ce53679c390231197553971d0d315b2fed8f6506bb
|
||||
B = 0f6d57ed815e0238a33f7028e552e40172546b96996dca7fe407f297164b5047d57c0b927db499abd6617199b62c3b307c9300ce4a1c8f03160d41004d2ad54a94402d6fc17521f1f4ceb3eda248d58de6d1660f803c45d210ea11f56c07c6bd975e533834c80f535e2d5afefa54857b3aea1381674c94d7484c7955459e8aaf
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 2f53bdd643b5b22445e2af3667a93de52f8bc7bc151e196c0ab0bf3b4e4dc0e5dae9e507508711a9e3de52e2aeece6aff7fc8a1db65588de3272839390a35a847e29204d3b9b70e10352c88a10c86cd33e067fb530d20a3a5ffe67938c5a7a9218f1164f36a73324adef64da64d5fa5540d29a76a87ce010fb7d73a59b109280
|
||||
A = 20d5bd41685173e10f25a46f4f276cb6b99e5cc361b4ea50e119c872ea538585d3255a005b4263fd86c5e51e75d83a7b923fbfc631d2b1759517e7983e6fec7035620839de347e43a814da4895c515c23b3dcb8829ee4920a6ffd2d7f8b3cc08b1390867c9de0d03f1adb06bb22b18c956026377f79322f78b28edac65823bf9
|
||||
B = c24e1143b337bb49c2a51d4546d45b24a754d2df0ef7b1c424a2224377c0bc560742ae8c9101ddf0ade3a0f5bc74f6c2354f9918baf48ec5c5395cf7368a0c933730742687e82f71da221f72dd7a8136d4bf38a608d266fe663aebac855ea7ec7f61c5546cef55d629b5a60744ef06feb1e8d29643c3f7792bec897915d88e
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 32d16f7ae2632b5cec2e90c34d191599acd9a1b5f97845595988c1d0d4ceb9acfafbc4aeee9924ce55e109ec88c57610fddc664316e0f9a5e3ed56ea447111c0383ecdf117ab42351b80e72720a4b1d98d4c73f5235507c5b4f7849d5e9b527d054858c0436ac3d2de2704c4bc25de4cc702f5880d5ae34094766938bee555c8
|
||||
A = 7a7a8caa1ca12e3eab5b6c974852f45f53b697db1ecdd17b04c5de36a4b4c90984e68a3c331c363a2b0c7d8e2c5886a49fc8f433c0e641801da54c4f40cc6f2cebe9bdd531524c8d3a19d232b40793e7b568c30b07488f939a8a2893b8bfdfa63f26cde242466b82d8d5567387c836b2c402255adbbacc23914ba234078d3531
|
||||
B = 8193b601cddaedefee05758ef0a550142eaa2b1fda6ad1e20a5a0e0d546315e8562781faddfe3c8271187a0d363673f817b3b3eff03a78064bd1c038297cb0cd749531c5acbafb87fa7a251e45291473d2709392a0dd29cc881a7d352bd93fe8272898ff57789aff3152f101afb73cc93047471cf52cd4f66f30d0d3015ecb47
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 20877c7f53fca97f8e484ba31f23dcf51ac0f4fe4c5121eec576e043c6ec5492725f1b9f9ecfa64195f71909500a69fab2e591377cc2120bd5f60d3fb3812f9e80b2f6c787e0081c1439dbea76b819ab44bf6bffe87dffd771a870e4f5502609249c5260f91175fb217a9eece4166540be877d564049389306e0d6b313706297
|
||||
A = 2ecd5ffd075fc75b53d8e43a57b0d3a4846ecad5ec51cd3648aa734ce2ac560ac098efeb6d29ead3d58d8d90ad3051a800dde6637b2cebee2aa2d35b659c1f8952546baf3519a860b6cddfa17a0cdab71f80239b749fbc904a1422f0253453f63edf45ef4416b7f90dc07054afca84b3766716fe32f4747fecb1a290fcd4b5ac
|
||||
B = 565ce4bdc7eca8d5bd99cd99ff6fb8ee8d47f717a0d2a58c30bed1b4faa46a4071a7aab50095af5fddf9fdbdbf2bdcdcfdc01b5300c07c078800d9ad2dcffaff29b762eafd00851fa6f7b4bac7dcac547f4d7a11ee5a4bf3de51f2cfc55cd592cca37c67d43f2f12a691b8aaff2ccb90fa34d17cacecdf27f132bca026ce6d83
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 24823628d4fe9540103ce5f611f8a6ccf18788120280179a40c2636f30a13e5076503e8a4b6b6ffca21da5b0f9f0d85feb2ce10b51292ed069f35289ebf5130972d720d20dfb8e6ee80c3ac598570d38e57ba33dbd75f1b03eab7847d865c3e8e471ccaf302461a6136dd13b8d31c9f163799a3c24c7284b8826608a9543816d
|
||||
A = 2e930c17984ed30e28ffab9684c369fa37ca2f39f6d03e2f7f7714c9a7d8afd41c64277fc5777f5be047e78b06c294e6f13cc25651be8f02b49cff58091de0b6137b7c5fcb9045be33a250895db9bbf1436f8fdfbe5721f281f0d1bc689c07fbd6199ae567c35587b51561d9ee3e0fb650d85c825f63ec11c1ef043588abfd0a
|
||||
B = 4e5a846cbd6e04d987c003d84d4c62db6c3130fc019b76d8798d1d0f0f01b104e91e86a4c71ff86f059a49b5c4fdebddb77bc3f79a584e94939414481def37ec40f04f5ddc425044f4b13b5eba12f670da79663d89877e35e3f501e496a412ba99316bbfbfab65339acaaa85c01563792abeddb8a3262bb6589cdef770a775ce
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 02c4bc23d0b4b1f79141be9149ee20cc9f1b58ee0a76d5f4205e0862492c18daa20171285d6ff0b600c358be487e78cb5450d151efcff8d53004eece94c5a37f49a15fb2b5f62a79568382cf0a4232407b139e1ec5a9595bee8435b4f138dd72fdc2946b03817e49864812b7b61f179bdd8389791178a95bb6311df0a5c60db2
|
||||
A = 34a806fb93c97f5a660926cdb21d66f8fb65f3585980c9157929226a48a9cf933f4dbfc8d5642f3a1cdb71f3e0f3d34a886093d1550e7a834797cf0a2765ec71bc40c0f6d1180e09c21d91be88057232fa9d0d321d6029eb65e8220963dc497edcd2688ec3350cb8d205000aa0ef0c7f03e5b9e310693f0f1e0c114ef3ceebc2
|
||||
B = 5dbdd8f9e6a63c183f3307d1678402953e333b19b5de0f637c4a5cec2e087b00eb389b2be8807332843f62696f9cdd1393777bcfa98edbad0a6cb677044e0e3733c15742d7561ea119f0f7a387341cfe1b7e4cf54616f27a487a34fb761f741c588c60f9d3a4e28ecb7b1cdbc0292bbfbf00baa44bc7c06da9a00ae0318400c3
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 36e1e0b44e5afc35d1e19e88e75f030569eb99d326721ced9bd7416ea7367a98305354eeafd204f1f8a652a8442eb0823d2e6644e6320933ac481a3709777381dce8a7c165b23aebf31b2ea2745ce5b352acdf0707234c824da9e1af98bbedf80e940fba00c229539f310838bd625f1fc103f267265ac1243855622c5df72c17
|
||||
A = 737962a54816deb28edbe9f7b92ced834b5ae03e65b7af3c70e218f9343f8a0a6a67bfbb163d8af18d40012111a5eaf873f48bacb730bdfa12991939ae0171a0758e101393fc65d3f58c636f900f6d68b7d3f45d05e21fe7271f477bc0551995018da1010dc74d548cdc576eda728492386086ccb225e80561b3217354d696ce
|
||||
B = 2f01dfad0b016691167e2db9392554cbb502d8e6018c8d95e5c9d830368ed80358387529df98b420423c08122852ef7969a5ca11c73b24910685c683fa3f0a08efdd4da6a06ef89336d32c0704851d361bbabd0163bff2b8680b5e86157a2ffa94c559291852520c1c94e65a59e2e3c26ac9c4deddf9029780d702e96e9129da
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 77eb3cb5277ced02b72368e41f04a35796c2c6cc1273f109336fdfa745aba7c755b6ff3833e9b124d9c78584f6bfda1c94273522f020371107870c288592b7c23964320729d2308bac8813586e72078119852e1d7706d8e15c195486b8d94358736869b15d59c037ba4dc8032ceaa31eac3a9e3dc51ee17706a6956cff8537b8
|
||||
A = 7c780aaaeaa1c54e74efb2e896b3ea0fb8be1dc263c73d0934024b28c932d5abf960a3a2bcf5d6befb8ad1f7a8c0a463b08638cf04dc2a65d8c69772299f7210445aad11a31dac561dfdad8fbd608567c9e872e07074ad13a47e2d153332b12074f4165a013134a79c6ba6020999c3c5efb7d01354db50bae7a4e4270d17a133
|
||||
B = 302f31190e24f25cf3bd902c25fb1ce7463da9239df24e9da7c362d977bc5932aa39455417328185394301d5510a404707bc70304fe357c090eec66202b42dd871e1d37b3b75d563dc54395af212dacfbbac501bcaf5b0f3dc83ba88b362950400f977790346a9f7f27277272731693960eefefcc82f507077b5b63d48016d94
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 660a1f378a23fc3b47f693a347d90640fef43add9729d74546933f4b78a26968cc9a70ad6fe8d85bf28164881bf7a99e8b96683c6f4fb54162c144f99a27e3feb736f0d382d7e5b934cfa835c723191e5692b7672cf6918c4a7a93b24af00b1beaf1b80320b14cf2d1539e3376779872542406a5df961f765e59f3480e1cd40b
|
||||
A = 518a4f172c7dede92821376b9da08aef36716b3d4744b1583ef82a18bb2429b22620b27b7470a3a038c588019f6c4ebc6010f2c18441a0f2f50f4172b7c4b8ab3f178e6e4a60e38b5c928817f62a4561fbe517c705622f4c48e4ba788ceb1077d1e0c9c13c90ad34c113056fff45f8b1fbaf3c3bd7c1e3c543848e75f8116a73
|
||||
B = 41de4428d0ee5534e1c77590dbddc8b86460561d2d9834a50a32cda9d5d210fa0ec5dd0cf0c4c3013b7eca2ffd48196c24a5fe08dbfe2694ee391bb950745ee67b32194688ff41af5886b616f8f109050bec544737d5ed8c00149b90cb8dda4f708d8e3f67141dc9ae34cddec5531e1090441114ba5b8e6af3338071c03e856a
|
||||
M = 8e2ba940fc5165c6c5f7f4cb56a6fde2fab687651099c880d38f6eff2889f6a3b2a3a186d1fee05ed452d11ac712cfd30340d22da763af7b2ff65a3f6e202e8b4f42cf5652c625fd9913b4a032ea9448591b9a839b8c25d2323cc2d0d3bf7a6d15896aa85237b6ac4c9c9a854a23449e30e6a2b7c4a2aee199bc20d30af280fb
|
||||
|
||||
ModMul = 872164b92b9426b237858c4cdafe1694f96b0e0e4c19e894a0
|
||||
A = 0c3255cb24a813e27c3dc410f0
|
||||
B = 0b144f39e7c2d33605ba7bee16
|
||||
M = f3639f4dfb782f3107eb402fabb5fc878903acb5e02e129077
|
||||
|
||||
ModMul = a8b3fc0b53df3b92753edecd6fbcc5f4840dad3a44da704e34
|
||||
A = 0b36249e259b303e453757721c
|
||||
B = 0f0c1db50670d92abd93bdc84b
|
||||
M = b05cf978bf2dc7e093d7d164e46d547219c480382df32b33d9
|
||||
|
||||
ModMul = 76ff291a02715fc87ebfb3e99153c04e53358dbd7beae43478
|
||||
A = 0997c4a7b537d9500d73a205a4
|
||||
B = 0c679ce666af284a459ae5a26e
|
||||
M = d0d0fd4922953941acad8beb65c00603b19eb44fb8ca51e3c9
|
||||
|
||||
ModMul = 8f4b8a585415adff3a7bc35fa88891ba31e4a82672c664fb14
|
||||
A = 09a2b56a54bd0727ab4be57ff2
|
||||
B = 0edf1781b4296567990773005a
|
||||
M = c5a7c3b97ba00d6f174a019c6d37eda52036c528f351bef0f1
|
||||
|
||||
ModMul = 7f8447dd983b113f04c6288f9539e53a2e9cddbca8b2fefcc0
|
||||
A = 0f67636b03821c8f13f21217a5
|
||||
B = 08473a29f4ae33f36a0d2c6dc0
|
||||
M = b829af37b557c3ddbb5257c8b19144b90708a45a274d6655f5
|
||||
|
||||
ModMul = 9fef1c18778a8691c5e71c0b5208e82778e9bfb632da0b7e28
|
||||
A = 0bd162c90bed25e84dd5b6b77c
|
||||
B = 0d887ee03020c5df356f091db6
|
||||
M = a2c2d45fe9decd93a0ca3edab8fee46d27ba23fad9b5294d5f
|
||||
|
||||
ModMul = 69b2dfb3f1d8dbb13e9e479f38edcc427d5968acb7751a226a
|
||||
A = 08019266c548982a520ab48eff
|
||||
B = 0d33c3e3b13576dcdb3ffaa796
|
||||
M = e6255103732475604df7c6f7ef7e6b49a8ef9e2b0c717925a1
|
||||
|
||||
ModMul = 88b4d86b2c1e1bd780e8d2499c2221e05fab4f9b7047c2a044
|
||||
A = 0a38eceb9c551f0e69a544072c
|
||||
B = 0d5f8e7c2d534b2b8985bfd213
|
||||
M = ff81809b84fb8eed3508ad891d3d8208249d8a902a12d6acf7
|
||||
|
||||
ModMul = bc5f0076a8c2f6cc8f4e61540d2d6f6d6b13b775b363dcd71c
|
||||
A = 0c170eaddca5295d6ec6272dc2
|
||||
B = 0f94a5685ced7661df2efbd34e
|
||||
M = fa6bc46aa05033af72aa42793e9174af2e3ba38992f33572fd
|
||||
|
||||
ModMul = 697238dbe3d395e81f20c9fcc8db30c234a1f75f3b2bc27438
|
||||
A = 0930b04224bc097ac1d8bae8be
|
||||
B = 0b79496a80e45212c4663e5b64
|
||||
M = 8ff7e19d967d317c255380411898d73e3786269f09079f19f1
|
||||
|
||||
ModMul = 8ce1e17972f1a9d2e9437d0c5219354728a5f31337808d7650
|
||||
A = 090e5d18b017118177ffb080da
|
||||
B = 0f8e7e09032574f6c66e623ec8
|
||||
M = da795e6ef63ff7dc4baef5c327022ccf65d44e3c4e24823f11
|
||||
|
||||
ModMul = 61d0ee0786963906a028a1df01f836841ab6d39d88ca2717c0
|
||||
A = 08e57680f213d088ff1a1e7db3
|
||||
B = 0afebecc9943b0093f87022940
|
||||
M = b6201f68a45265d7e9183c3255feb4c110c05dadbcb13881bb
|
||||
|
||||
ModMul = 861e7ef401866f815b983ba18a612913ecc20a67016d79cfac
|
||||
A = 0fc41a9ce06e882942f751be7a
|
||||
B = 0881c05a51d1ba8134d126a48e
|
||||
M = b12200b39526c33b70e8aa23ebc400dea0d4d8fe42be103d5f
|
||||
|
||||
ModMul = 814030123025d287aaa8b826792999d72f2d589e0c7f7f3dbf
|
||||
A = 0c3b33f391e78bee97ceddf313
|
||||
B = 0a9136f3af450fdeb245eff425
|
||||
M = b6aa9c517eaecb70781e597b907583bbb569e970d229235a35
|
||||
|
||||
ModMul = 8b16b82f064f471983c7154abc9f9ba355111bacb90400372a
|
||||
A = 0acff8da571e1c96810bf95707
|
||||
B = 0cdd23e5504cc26d0c34a62b06
|
||||
M = f38902a99190ae0b5ef26849a6e943d651925666fea271fee7
|
||||
|
||||
ModMul = a31401dfa761bbe82b66b5f094151865b18a4ba75bb9b3dedf
|
||||
A = 0e6f48c027284856aaf3b96425
|
||||
B = 0b4c326f72a6a22fd4b93ba5b3
|
||||
M = e57d9608ac6e5b129b2c014958bfc59137f63838b1ba88a4ab
|
||||
|
||||
ModMul = 4a8573dd8dc50a4fa39f3579d3869745eb8c1153ca508deefd
|
||||
A = 0855f941d085305725da617f5d
|
||||
B = 08f09b7d2c36e0340523da5421
|
||||
M = fd8caa05edeaa81beefa01957eed97a981ab34bdeb6d8c704b
|
||||
|
||||
ModMul = 81df390c9e51b30bd639db15adb464c7cb1d011cb5e260be58
|
||||
A = 0c237eb242c40960861c938c08
|
||||
B = 0ab2f481f0d768eebd90d2574b
|
||||
M = 8697d7a28a5f42c9a7b31949b8b568f861142f44fe66c6cd3f
|
||||
|
||||
ModMul = 0761438baf5b02dc095b7040e082da7b167c2b9ace956284ed
|
||||
A = 0fd91701ed2151f8e994bf4ee1
|
||||
B = 088b66e735b76972bccd9db182
|
||||
M = 8008b2d1274456aa68dc627b1ec3e1762c6ed2d660c64a1a55
|
||||
|
||||
ModMul = 6e99aa5b8107399848cf24fbd88ed6350efb68d737e505b466
|
||||
A = 0ca6c51ba2f410d09bf71d60fe
|
||||
B = 08bdfa8fe5ef3b2ad02bc63c4d
|
||||
M = 84daecf412b8c50ad6dfdb546c3eb783dcc6f32003eda914bb
|
||||
|
||||
ModMul = 0536175913582e73c1002083cb0cfce5471d4193a5b717881e60abfe927c829d
|
||||
A = 0161d774df9a787bb5861d45ff4933ced42254532e799233793c81fad319c566
|
||||
B = 047c09252d9efed9086fb2fb1fed44d7157a48e642a056824790d6e81b4c1f2e
|
||||
M = 05efaeebe212752b28b5441a5d0b2600190504467c6359e9ab26320ee72cffcb
|
||||
|
||||
ModMul = 06161cceee2b74e7965a926fdf5344ddf8cc41994d72154a8b6014c18cf71634
|
||||
A = 05f37c973d1aadc7e8a15a6cc3d2c7b20d2c1e30fbeb7554dfb4cb93334edbb2
|
||||
B = 06d98b39fc484fadc8eecd32c5d1652c3dca69343f07337e9d25618b3fe1b36b
|
||||
M = 07c3e3b8b1a6110da82674aaf88c288cef4cfddf22e7c9b75640fd67fa5fad59
|
||||
|
||||
ModMul = 2acd55bdcccd55882eff0bb262bb62f78bff8e932aefc9d32f54d5d4e9b8bd76
|
||||
A = 17ef930743334d382bf1f66d37add6e8ee819545997ea6a5c58e833acf159045
|
||||
B = 28af21f28b148683ad053aa552db604236f03d61d398f29995b9e091460b7888
|
||||
M = 43760c71742e9cf22cae6fc262c008b7f1b97a78c8063957b74aa4cd370c1eeb
|
||||
|
||||
ModMul = 504c11e38284a30e3647c1ddfaed94503d833bcecdff05e749422ad1d9442540
|
||||
A = 9231bd46ae8543102fb06042e019c9411c5a3b67f540d730f359e9e77f1f4645
|
||||
B = 1c46a398183f9a162b211d4487ede53d4ddfe0a35661fa87c9b5884cd67f5df8
|
||||
M = d79fab3eb31189268b2a0689cafdaa0826f07d432591e8aa8bd3c7cdce1470a7
|
||||
|
||||
ModMul = 13a6431c57ddf0ed3979412ba8454a0dd9a2694a0dd76453aae63366c46e41db
|
||||
A = 0aa2149ea0f02dfd92841cc2c44164bfa6d4c06f2bc8df7b2e027a2b82a60336
|
||||
B = 16b9ed5257ac10c4727e467b3bd012f6ab3cb59b666e6f287bbe49e3c4a0f92a
|
||||
M = 182572149b860615dd853f37f7d51a35e85f5e4a4249a60fde58dc68e0dd7401
|
||||
|
||||
ModMul = 0145a44566bd75103083b7556a822ea6008ed3a6a1bf135b68fcf87a294c09b4
|
||||
A = 10bf9cf97ae92b444afb3f94b355175560f9edc033f9635f29d97ae10e434427
|
||||
B = 29509e418f2dd8a84ebb52ef1112df765987f1036149f6baf7be82c96a11bfe9
|
||||
M = 29b060ee2aef7e43e02163d279ce49259127198adf462d13aa195c7dccf573a1
|
||||
|
||||
ModMul = b00740cef7791692d45f5a7110f3eeb260638f19f87c9245436fc0422de90658
|
||||
A = 8f82b047f3e2a9bce8699d4ca12ce4662b04239cb817bb36ca4ab5ed460bac59
|
||||
B = 3caa56f9c57ec4862263e6cc2b422b3d8e98517771f8f7b95c87b44a7a202818
|
||||
M = f975a94fa62b4c0e68df5c3ac5917d18927c0a6d9cf39c26f6ed97a81cedf227
|
||||
|
||||
ModMul = 0dc04b6ba2eb1e34ea8942a50d1d0c5479dd22109895796ffdc9cd32b53d4764
|
||||
A = 1abd1fbaac8fc366dc669f2abf2b5cf4c710823f6c57d0fce95f34079c9fa291
|
||||
B = 1fb2f5fc58e3802dd9cf0a72a99d0f9641acc9f1815f0face7cae83ef1a81792
|
||||
M = 22e2856f4c2b6c01448d4aef74aaaee3a14e9660b5b277200f2e67464ecadfab
|
||||
|
||||
ModMul = 19299c9e960ce15087e9fbd66f95cafe82546431b92d70db1de87c3425c1bef2
|
||||
A = 6e30e65129c92bf2b24a6ce45592045db370f9411153de793e2af9cc0fcc0f78
|
||||
B = 9fcd13fb2e81666f168bb764bca62894aeb6a1630bb07940708e6b1f374e8b57
|
||||
M = ab6b4e3d3909512f5d1d62a30c1ab8dd5e584cadbce9dffd12fe203f8936ee93
|
||||
|
||||
ModMul = 4f88ad4e30e6e8e38cba0452d98d4a3547c680f16308692e33e5577772658764
|
||||
A = 04a4f1814509cb369bc9f20d641848fa4358217818381d0f8aa4debd43d0ec4e
|
||||
B = 9b6ec67a72b0868053f926be4177def0e8bef7915ab48d239e6ca9aea4207147
|
||||
M = 9ba20dd78923d8ef82897ac46a509cf22c9b7986a4facf42e5416bfe3576a735
|
||||
|
||||
ModMul = 0985a4d2a7431e09fcad03e6a3f926582dbc0aedc588f17aa5db40c2d3566233
|
||||
A = bc1795a68aa5236a8c1d93aa4720717d4d77e19bffa34d5126a0c3d97f5ccd68
|
||||
B = 60aac3751c58eef00fa2ee3fe096bd7060d05974175bfeb6a3f444010d789514
|
||||
M = c66842e0a11ed6ad1e8f192ea97f5f244536cfc5234c7fdae1ff905123c72793
|
||||
|
||||
ModMul = 0133d7b31537b627da2c042217cd28625437c28c3e06258427d9a4384046a1f4
|
||||
A = 037f8b1280f927ea374c105b87489355be4f9bd26cda85c1d76af4c6fe38eb14
|
||||
B = 03ce98c25f69f6301590b3d163b462239f42e0202af1f692663b40d59bfd0982
|
||||
M = 03eae4f0d6c7e1fb9de1a4c160404a8767783c7f839fe27a543f5c389c679d47
|
||||
|
||||
ModMul = 7f4576a315bad5c7fbb1616e8b26c5b34ca6f701b9b1adf0485fec181c41dee9
|
||||
A = 281bebabe6be0c8dbc84f47725180a673c6bc3c8f49159665f5749d6ac1efcd8
|
||||
B = 48affb05091c691dc0c6ae2f0fe497be1824d2a33a87bed6b29cef431555f5c1
|
||||
M = 9975d8e7f2a4d9d1ff8d442b93ff269a83fee43a18bbfa8c2ccd7ca5fac3a8d3
|
||||
|
||||
ModMul = 57ebfb39605d4fa6ef5fd03bd8e4fd685664297c29b7ad75a40b133e15fc5ae9
|
||||
A = 6080c661828ae2be3bc23874b6f6b23a125ba03db461382bbb79a8619e8c0845
|
||||
B = 39e1fcfd15db0040413690d12683bbd68ed496c5d51769fd3a6ad78016de0677
|
||||
M = 7704390c4b1da86d51ff817003e5451d601a5352296e339e5da219ec5a330479
|
||||
|
||||
ModMul = 040b6b0d44cf8a5ca7f4fd03dd6e1e2a11f74f3911dcd8727e57db8d65cd490d
|
||||
A = 3a9479beb52316aa872fa1d97646419987d7ebc3b1f5009a58afb4d0126cbd04
|
||||
B = 3538929797e8f26ff071e734a3f61aa99d36150b8feac5eb605fbd6c03fd9823
|
||||
M = 5c0781a87b84ecb4362b09c623d511de53c085671dd4f08e9a551685b55ddfd1
|
||||
|
||||
ModMul = 6b778ae9822221e6a8376379e0032d7edb14d7b5e32a7310897b54d1d5626113
|
||||
A = 21dea2aee0302de380cd990954b4a18e1d52b5f30a0cb70f06c40290c9d3c6c9
|
||||
B = 6e1afa44d3135a7dcb416031297c91b1d4193490573b4050f9c77613579f73d7
|
||||
M = 7f5978c0c066132a9bdcb00727bb802b72777b9e8e4265f76b80cfdc3a788817
|
||||
|
||||
ModMul = 5c717e5dd25abe60f761d6f9326ed056416add4c1384682d87b7ff12e112f855
|
||||
A = 51f5a2f115ff6fbb007c54a677dc2049f9bd99e1fa1b88989962106cc3d2f53d
|
||||
B = 7e120151b055335cecbe78f2d5f129e034fc6b30ee463feb50cf95d016b1db99
|
||||
M = a6c789884c66c7f028099e0367b3ed86871277bf070c541ee12fc02fcb6181d7
|
||||
|
||||
ModMul = 04452688244f542125168853f1d444f96ab0f82903bb12a97e59f0db633edfd6
|
||||
A = 136aaaec4b34d7878effa8057d78012c897d1757a5ff2fa251cf673b793afa81
|
||||
B = 19447559b08dced853b2359d15e098d70a3d04328a0177f471617d5231925088
|
||||
M = 2c245d407a78903ef2b279ddbe32106e6333b6f44cabf87b8641b047c79ea06b
|
||||
|
||||
ModMul = 375f8474ee47df6b9a038512002e56cddd374d69c69719d8d369232c64a839e2
|
||||
A = 0aa566b24fd87925fe8f9690f62586e4afb979c65419d7b11dac582fa0ba050c
|
||||
B = 2e0b85b7f590a1a8e8d0e3575ffd5fe12196b7fd066d430944181720e5134096
|
||||
M = 4f506313a4f49873a405f2e5a6e9cfae9cd5e9f67b5ef900153366570e28a955
|
||||
|
||||
ModMul = 036fb0733a26902f0f8f11625305a3c94fcdfffe294eb6ccba110aa628a314df
|
||||
A = 09a8939689b47fb66ac3ad543034302046a47c8ac325ee4d18155e2cafcb8de8
|
||||
B = 09b568319788264cfc18d36fd50c1375a43f2e524fa44fbc65fe12c96e2d7990
|
||||
M = 09d7c334aa33634f9f313b71b42476a3b627a6c5bb8ac1d07a8d732d5c087bd9
|
||||
|
||||
ModMul = 4a377267508eb045e00cea66a417112dac07545304bbeac6315625275b7cbfad
|
||||
A = a29e606ad0e4926a3458b5853ce04196edf42dcd88f49936a90655019b633ed4
|
||||
B = b119f89e0b3ef234456b0421778e42f086498a2ec67bb32ab43bc8e0012f3141
|
||||
M = ea0477e7f1a02cb6c21171066f3dab69d4e24429043b0f049de660fc80e51937
|
||||
|
||||
ModMul = 7952dfdb91252658430e365adeefd9093740de92cfc9dd3d92294f2dab6ca0b6
|
||||
A = 9e1693d9e37c1135acef80e49ae1a74e9b244a36179a2984f5c4fce69b1dde2b
|
||||
B = 5adb9fc6429f638912159f876356ff09157e7bff1073ef8318a1397cc81f89c1
|
||||
M = aa46853682af960824140c35d145a6dcff6283b2c59994b30ecf9b8def41a025
|
||||
|
||||
ModMul = 1aacec7f7e66b0cf4eb2dfda9d8d3fbf4eb8e928cbbc967d13e3e38612f0346d
|
||||
A = 514599c8c352c6fc850809c6dddebcdd61c6a66edde608e5b88661120c54a44b
|
||||
B = 059dbf4bea3fb19fbe0ded8c4b0c97fe7b2009fad54775c46d4ceb5f674e11a2
|
||||
M = ac4f0a2b22df691331ded955a5d0e7d1910d7920a59d4a87636b2635397b7335
|
||||
|
||||
ModMul = 2c25d180156fa7d2fc20c9bd6d9ff0b111c9ad76ada0784e2f8fa0bd06413f66
|
||||
A = 15dbf10ef83b811d7ef146856243b071f11b25ccca14e62e4b7b4894d91a44ec
|
||||
B = 556803f5718085a69926a0b4216f6d17b78e1da6db3ff343b34a338a5ffebf0b
|
||||
M = 65c9d79a09a820adbc9beb152bef387c1439147ed50cef872d36a69f1c7d5fe1
|
||||
|
||||
ModMul = 56ec8624fc199e7b4e68358f88f1a99f1d4d02577b8c6f7e28e4ccfdd981f995
|
||||
A = 57ffc478a3080928ed66505778554e38b40c0f47904fde89191c9c6a3453e82e
|
||||
B = 4b11a10e8160e6e4dbc4ccf3075daa86943f90322dcbc0ad63f6a9afc9d94772
|
||||
M = 73882376ca850c125ce9f20c291e550ee48f0eb0d571109ab08c22d6719496e9
|
||||
|
||||
ModMul = acceebe131aa34ff21b3235f045bccc8a8f762dca20c1dd1ef6eb461ea971c6c
|
||||
A = 74ecd7b4f7e0425b4934e0f15949af3ee0f1205227874fb536df33ba6b16a955
|
||||
B = 958ad144e29c894d6346d514d1e52eb0c561473615c61377f0f2c8f7cdd7cf9a
|
||||
M = c52ae49e1a4b21ec392b76844ad559653b7b9f67a58b3bba6c2ce250017eab09
|
||||
|
||||
ModMul = 62b5b04dc84bb4ee04934c03ef361bc6e59b42144dc117b9f7771525c67c3688
|
||||
A = 0c518f9c8afea0eefaf1c57283e5034b2b32fd5f64dc69f4baaf3c38bd337de0
|
||||
B = 2e8cd7003baae3fc40353d2e9abacaaf4482a85014363393850e0593fd538ea1
|
||||
M = f73398c32191b436d14a0b76c6069b1d61395568753c832dd0c707780a232dc9
|
||||
|
||||
ModMul = 5613c8fb0721bd3f605089def48fb2c38a4862bb387886c1edc1bc37d10f0e15
|
||||
A = 1c685e64660dec256a9e80822e029bfd90c556453a0b80311d6c1895adc6916b
|
||||
B = 34674001cd0977d54e600640c4d07510bcc0b69f6bf7c991e8a49351880348f6
|
||||
M = df8344fa848d1066afe4f8d985cff65441751677dcf3a4e99b40365fc3c978e9
|
||||
|
||||
ModMul = 30325f7ccbc2c69e11d739ad7132a947c53377aa902ec70b152f3a75e050c244
|
||||
A = 94d84fbeb43247cceed9743c5bb60afa789c674ef02423b0c21da2c4a059cb
|
||||
B = 176be45cf53003f3885361d9f4a1146acbf11926e7640dc79abc0f1c84918a7e
|
||||
M = 43d57108eb0ab9bebaa8ce137628ea825951c6accb9acb7f1e991c93b8563897
|
||||
|
||||
ModMul = 1975db7b72434ad32c9aee412645f6670b7f4af1f8a424a5031c559d3e18dce6
|
||||
A = 1d135f8832d2730000bb6489e74bf27990b464f2a0df66daee2b80445b3aeab0
|
||||
B = 27792d4be70d7f7f3e6900ef689a474edd84a2eacea94ce6384289ced66ddf12
|
||||
M = 39d57af763eabe569dac1a103e169e6e3b4375168e41e5c3b961b6e743915923
|
||||
|
||||
ModMul = 3bbb5bde9e3e240694326571360090e1fc0a4ea7b2311c1e0bd3961f6c159385
|
||||
A = e769a7536b8df131ace032cd184a2e40812d83276635a5592e97a201d8770e59
|
||||
B = 87adc45fe2433e78d6ac5d6f1678186a1daf336bed3c03ed6c993349e40f7d8e
|
||||
M = f3b9833a303eb540cf8b6cbc3cf16394b1634ef517be57684e42d364d8bec3e5
|
||||
|
||||
ModMul = 2d8174211f0367233b3a8df7c5bf0066d6aa792be7cdc5e850a477454d5c829f
|
||||
A = 2e8b2ffb36d54495286df23d1a5c8d230c23da069106830c829c7e3170ddcddb
|
||||
B = 71105099df4e2dbe198631aef3475c60ac10828c7beec4cd8d027324ec531fe9
|
||||
M = 7eacffe21f88413af94155a2a8e37f70a431a59653738afda04a1bec72d0d9ed
|
||||
|
||||
# Regression tests for CVE-2016-7055.
|
||||
|
||||
ModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9
|
||||
A = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878
|
||||
B = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81
|
||||
M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf
|
||||
|
||||
ModMul = ccd6f75b5f24b7c5ce2ce755fa89c2450c6a7d96ce8c8791e659eab84577a7695e3b2caa7c980fb23f60634233e9798499c28b0338c1f1a326d0ca89fd41f2fd88b759f317889832966b551a950043ec7a4b6152d3e2cbfb40e88458e70ab783b96f12d271f828d5b39e198ccaf8665411d85026282dbead5d24cd01b6c8a8e9
|
||||
A = 095d72c08c097ba488c5e439c655a192eafb6380073d8c2664668eddb4060744e16e57fb4edb9ae10a0cefcdc28a894f689a128379db279d48a2e20849d685939b7803bcf46cebf5c533fb0dd35b080593de5472e3fe5db951b8bff9b4cb8f039cc638a5ee8cdd703719f8000e6a9f63beed5f2fcd52ff293ea05a251bb4ab81
|
||||
B = 7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878
|
||||
M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf
|
||||
39
zeroidc/vendor/ring/src/arithmetic/bigint_elem_reduced_once_tests.txt
vendored
Normal file
39
zeroidc/vendor/ring/src/arithmetic/bigint_elem_reduced_once_tests.txt
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# 2**1024 - 105 is the largest 1024-bit prime.
|
||||
# Q == 2**1023 + 1155 is the smallest 1024-bit prime.
|
||||
#
|
||||
# import Math.NumberTheory.Prime;
|
||||
#
|
||||
# main = mapM_ (putStrLn . show) [prevPrime (2^1024), nextPrime (2^1023)]
|
||||
#
|
||||
# cabal install HaskellForMaths
|
||||
# ghc -O2 prime.hs
|
||||
|
||||
# N = P * Q
|
||||
# P == 2**1024 - 105
|
||||
# Q == 2**1023 + 1155
|
||||
# QQ = Q**2
|
||||
# A == N - 1 > QQ
|
||||
R = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9cb3b
|
||||
A = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2644
|
||||
QQ = 40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000145b09
|
||||
N = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2645
|
||||
|
||||
# N = P * Q
|
||||
# P == 2**1024 - 105
|
||||
# Q == 2**1023 + 1155
|
||||
# QQ = Q**2
|
||||
# A == QQ + 1 > QQ
|
||||
R = 01
|
||||
A = 40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000145b0a
|
||||
QQ = 40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000145b09
|
||||
N = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2645
|
||||
|
||||
# N = P * Q
|
||||
# P == 2**1024 - 105
|
||||
# Q == 2**1023 + 1155
|
||||
# QQ = Q**2
|
||||
# A == QQ
|
||||
R = 00
|
||||
A = 40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000145b09
|
||||
QQ = 40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000145b09
|
||||
N = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2645
|
||||
171
zeroidc/vendor/ring/src/arithmetic/bigint_elem_reduced_tests.txt
vendored
Normal file
171
zeroidc/vendor/ring/src/arithmetic/bigint_elem_reduced_tests.txt
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
# R = A % M where 0 <= A < M**2.
|
||||
|
||||
# A == 0
|
||||
R = 00
|
||||
A = 00
|
||||
M = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b
|
||||
|
||||
# A == M
|
||||
R = 00
|
||||
A = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b
|
||||
M = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b
|
||||
|
||||
# A == M - 1
|
||||
R = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033a
|
||||
A = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033a
|
||||
M = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b
|
||||
|
||||
# A == M**2 - 1.
|
||||
R = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
|
||||
A = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000000000000000000000000000000000
|
||||
M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
|
||||
# Test vector adapted from the regression test for CVE-2015-3193, A is the
|
||||
# square of the original test vector's A.
|
||||
R = 19324b647d967d644b3219
|
||||
A = 19324b647d967d644b3219
|
||||
M = 414141414141414141414127414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||
|
||||
# Test vector adapted from the regression test for CVE-2017-3732. A is the
|
||||
# square of the original test vector's A.
|
||||
R = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001
|
||||
A = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000000001fffffffe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffe00000002000000fffffffe00000200fffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000000003fffffffdfffffe00000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffe000000000000010000000000000000
|
||||
M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff
|
||||
|
||||
|
||||
# These vectors were adapted from BoringSSL's "Quotient" BIGNUM tests in the
|
||||
# following ways:
|
||||
#
|
||||
# * The quotient in each vector was removed (*ring* only calculates
|
||||
# remainders, never quotients).
|
||||
# * B was renamed to M and Remainder was renamed to R.
|
||||
# * Only the test vectors with positive inputs were imported.
|
||||
# * Only the test vectors with odd moduli were imported.
|
||||
# * A < M**2; any larger values of A were split up into multiple reduction
|
||||
# steps. The first step uses the initial A and the smallest power of the
|
||||
# original M that makes A < M**2 true, the subsequent steps have smaller
|
||||
# powers of M using the result R from the previous step as A, and where the
|
||||
# last step has the initial value of M.
|
||||
# * Only test vectors with moduli that require at least 4 64-bit words to
|
||||
# represent are included (*ring*'s modular multiplication has this lower
|
||||
# bound, and modular multiplication is used as part of reduction).
|
||||
|
||||
# Step 1
|
||||
R = 04
|
||||
A = 0813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b4
|
||||
M = 813bc46ee19ffeab364073a89f96913f340d43ee72129ea9edac1beb4ebe1336450d2eabc7b26e51c400cec60d6ee459033b
|
||||
|
||||
# Step 1
|
||||
R = 18
|
||||
A = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd000018
|
||||
M = 966df62c26acab2d3d1dbe729e48d0181c68e9f5eba45f6caefa38d60e34057d09fe620abb8640cec8cac755957aaad7c6fd
|
||||
|
||||
# Step 1
|
||||
R = 20
|
||||
A = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d00000020
|
||||
M = 89a2f1792afc54467955839eddc9ef2e37d391ce7a1a4a205291220c1f49f59ee31fc7a7a7f7706c199bf5c8c951a0d0743d
|
||||
|
||||
# Step 1
|
||||
R = 24
|
||||
A = 0877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719000000024
|
||||
M = 877f1caf75e7166ef18484d0718947893fd1ec016984387debc55c19e378a487a5ddbb03a80a88316f6fca16ae148933e719
|
||||
|
||||
# Step 1
|
||||
R = 2c
|
||||
A = 087bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe10000000002c
|
||||
M = 87bd03a64d9c56fe340137065ba36bd07b556119546dd1fc3ae087ead32bc79ca7efb5c7230ea7bfb00ad419096d9279fbe1
|
||||
|
||||
# Step 1
|
||||
R = 30
|
||||
A = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7000000000030
|
||||
M = d00fec043edadc093673e5f5abef0c6bacdf1f3faa49a831a645bf80db7539d657f69403b122a5c6f879eb8e63be54d35ed7
|
||||
|
||||
# Step 1
|
||||
R = 458f5c63c063b09790a28c6cbd9afc98ded6d6c1d12c8e4e081e4f6a5638a5319a548fe711b3142d6d32827f415a41d457048783c3
|
||||
A = 01280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031
|
||||
M = 4e5d7ec324e42afb2d8b381c6d07869985cd3b3de3cbc06853a387c076e6525fd93c3b6de887f31a7580bafb0546f45b785c4e5199
|
||||
|
||||
# Step 2
|
||||
R = 029abc8898d5ef85f87323c2a6fa36ab6e1bdbcc0ca742b1a2347e
|
||||
A = 458f5c63c063b09790a28c6cbd9afc98ded6d6c1d12c8e4e081e4f6a5638a5319a548fe711b3142d6d32827f415a41d457048783c3
|
||||
M = 08da37bc9c7c9bdc62f49cadcd40e156e776b7f4c8f7ad543f463b
|
||||
|
||||
# Step 1
|
||||
R = 2000f9c8569d20abce69ced0d66a44ae47a9516205732183408c6ab6c135cd172880f0c0d160862d49a0003656276f3884e88a3c9664d45f
|
||||
A = 01280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031
|
||||
M = 8406162ef2dd175cc81e309b0e1460dc5a007e3fd5937813e6ddb894a208a249c8448a782379e757d3533a0ef008d597579ebae1b4cd95e9
|
||||
|
||||
# Step 2
|
||||
R = 6c9e547a77c98eaba1b021777dbd98ea88f7fd37c95a2b182f2b9067
|
||||
A = 2000f9c8569d20abce69ced0d66a44ae47a9516205732183408c6ab6c135cd172880f0c0d160862d49a0003656276f3884e88a3c9664d45f
|
||||
M = b7d7b1f95f4fe2f267af88b81af88fbdf603e54ab6de73ccd000c32d
|
||||
|
||||
# Step 1
|
||||
R = 0bbfaf15a90e744dc4a1caceda3cb339e5491e4507a1118613c5e9739f976b
|
||||
A = 01280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031
|
||||
M = 82ae783b8a13e2e65d52dd3a6d6b057163347872f4d72245ff364dbf2421ff
|
||||
|
||||
# Step 1
|
||||
R = 82e3fb3f7252dd87b5370d26d9e8b9e98c7d333701f0ce8a05c337054c7aeb343d04d7e342
|
||||
A = 01280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031
|
||||
M = 8faf8c0a3ef94ab1069394998e5412a7d84f44aff97edf63abc46d96f897172c38faa0b13f
|
||||
|
||||
# Step 1
|
||||
R = 65bf2ef1c2f8e94d98060aa305f85e6cb869c74eabad99877010d30654aa2e578ef6aa3c5f1122e3
|
||||
A = 01280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031
|
||||
M = 83cfc25e90a61cf8686e3d5857b2f958674d478622c54cf8427275ca5e9312ed24e44ed4a1b5e413
|
||||
|
||||
# Step 1
|
||||
R = 02c89373720b834d718ff3df985ae47c3a7cde0e0309f682f5fd48dc97a1ff3d69fa0dcaa1245e956445
|
||||
A = 01280d26263c574f655ea63006f2930666fbaa4de1b09a11ab0e47dbe0054711aab90a05b1185454dcf046745436391a673426000000000031
|
||||
M = 0d6721300e877a8145d05f4f3d8085697c2ca5f34a5357fed0bdb7169f83b6f8d855232eeea594846b79
|
||||
|
||||
# Step 1
|
||||
R = 1b02a7b97f9ac1f6306aa00fff0e59f55fce463ffdc640364a950df29474e08b67cdfcec0628e973d42fa1e4f98e988ec4c47e4915651a1731b71d5e36a10a0d1b3420427dbb79ba7d52
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 3f74cafe9ab0c1b307cd7571fd442665fa3205fb2f45b3811b92d1d38b096a2025b8170663a29c52ca84da102e62048e583fba96a594c0b23952fec587814857c25221ff2cd0533cba6d
|
||||
|
||||
# Step 1
|
||||
R = 13849ef93cbc77460c3c496e8f31f7e01a98c21cdfcd6877547161f9601680665b394933d3a0824f0d32854508c89f0e4a0873280c779c7ca636cd89cf6ee5d42a917b4f382be3b9654039f623c11b43164827f870fa0f0781
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 23ab6042240a7709d43de7ee17332a9710bd0d913c42b3591341527bf48d5bc30abb962482292d45a15cb03c9457cc8d78d1e00aaa63358427b000e59e4260bfe1e2cc603e175d7fcf02bd9f61fae3740cb8e10a510ea3d1d5
|
||||
|
||||
# Step 1
|
||||
R = 0d8c77134a75584ecd5ab29e97a909ec139464901f9cfcb1d3d9e29a63d204615b6845d466c8710873980f107c40ab54eca9f8933ef6d726f9bd0f3e9e97eade5eb1a9bcaa7b01b6ad51ff3ecf67d6e4d345f128e990494a2db434fcd3ab
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 3e7dd961be36c0c286eb9e78bf3b33e6f9bdf2c2137a0c660f1d21dea31ac9a044e526bf47ec8190e137a60f1f55e947046b9cd04a2485679e48cac80a1bb064a915208889289d63a6e338cf7069ad799861c31ec6eafe02a4ef2c2641c9
|
||||
|
||||
# Step 1
|
||||
R = 0a1a70f674cb141a896c4adace0dc58cdcbe2503fd0ad36ce348dc5b8afc96d0f2f8c65bbbadabf2920012798b7ccaedbe8d896dd2674082ad3cc75b54c5c190ad56ff34e8cb5dd29c031656497d48571295d6da396d5f4cdb652732d874a79a674d06a1d7b979f5
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 21917f48bb8e65646c618068fd9069c06e22ce8c679a845f9c4ec843849010abeee12e2d3c61fb963297abca30813c446f2ae82e909ca6ac7839fb58974fa65f3b5d91fb8b3f99d948519ed56653d50026d694060208cf48e3c757f64885b4ed4328c6f071e9f5d5
|
||||
|
||||
# Step 1
|
||||
R = 252d055186ec896cb3142c9e4e49c441e2ddad365b86ad21ae4ef1c522d3306c2834d6993a5e1f8c64a1ed582bad8ab746f7e773fc004b1c47814f73560db72f7237ef6e2f671d3b19a8777be2e4c662a76db87ea64f32c48ea371b1ffb15df26726854a417e18afcf49054c6d2e0e337e71
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 2b6eb2caa3ca650be02fa199e9ea6c48646a76434e268713753a547e49571f9817ad396f2cb7b16d307801fc8892f0af3e7f93ce08f7955a8acfbc0b56add4b4c7ef7351f60e402b9a8ef7fe02ccdcb4b00b7ffe78c7009268dbcf1d606c3a1b5307d9a8ee6121c6a635a742b8bf36b56cc7
|
||||
|
||||
# Step 1
|
||||
R = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 3a8682d0e5a4efa985dfa8bbddc2c0d72a4400b8b070a8cf7450aa8f831d8a91c9ae3542641b7a4ad793e232a0d301b82664fe2c7f20bd9bf8275828a2a20027d6056b211638b9b0220fa4252d058bb485dd3c4622b1eac97d54b9634b558ff1bd5bd11085d4f3d288f7965af52beaa922b23ac0207d5763c24c085076128e0ef7370eeaa19d
|
||||
|
||||
# Step 1
|
||||
R = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 33aeafda3cfc20710f0b4a3d9ace4817eed80ca57ce6c82dc2e7946058a40983c9204ac95a1399fa633bc96cb10af3ddeee3ad2337c64391a42dc7794fca629e3e1e4e03a2ae24a000e7113b91c1b6230cce9592e45b6ee7984680b45aa0aabd7f56cab1a64ec310cefe5211821a75deef2e0c8e43eb467dea79dc8c03d2d523734498d079d5493c904a2ebfd8a3a9bd
|
||||
|
||||
# Step 1
|
||||
R = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 3083421e375f0722b9397e156de47f77635d62ba1d51794469371b473b71c02e3722841bca2ca06b5d1cf1492bbacfa0abfe394dfdaa7bb8787550ddbd953540e9c97631d9a1efe0c8f8e14f395c82d20245cec6d8021f8564b4d66e7779c3245734c56fb74481172f4e349d9a113cd0ee5263c69ebf746c5285cd4c0fa91d9531f769fea3610c2972ccfe9a22c00aa62ebf52b3a4c6135f3069
|
||||
|
||||
# Step 1
|
||||
R = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 2f26e156b3b1117f7cec542b20fcc06ca66cec03a19b6f5eeebf22b4c0fc265df5ff06fc9dcac569735135bdc142b526b295225711efb71577b10aacda2fa446f5208487c725407c2188b3185237740c813e4455a6f1dde4f62916237f23164a3471aac0fcfe24ad1ce1dd81a6144f5861ad0cf22dc337abe10fc4a88b36116dc4929602ab48eb971fdd7a5ff747d6b9e0b2bff75c59621550991966a0a19f
|
||||
|
||||
# Step 1
|
||||
R = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
A = ea87c57f6cdbfd4f836431be3e9950c90ee8ecc291eb4efb881617512fd62e2d86caefce713cfd8a20f4b4925bfc7dba1fcbe99c72932725b5d11eccefde4c5e505952754891e9ded499ec453a1c01a82152c8933f7db4f2b4b19e97baac322eb483cd661a43e458774ef27a29a19c3562ba466381056a3b92c35d9b8b71372b
|
||||
M = 2a8f2c530342bb6ce683a760540e956a1155c0fe065476e400caec59861ca97ca71e51a11b3213b2baea1a41a29449998778e0f533fcc181698d293f05e28bff2750ef4095170de98a19a36ddcf59a65f3789a3808ead51680245070262c9544e446f23652eba47065a2bc4701c55378bd49733619ed2c213f8ed12a4a317c465f37efe07ff2df8e88fc33d3eb42cde9408dda28215702bfa607030839285a8bbf89b5e8842fa7d7f50d83fd4ab5
|
||||
26
zeroidc/vendor/ring/src/arithmetic/bigint_elem_squared_tests.txt
vendored
Normal file
26
zeroidc/vendor/ring/src/arithmetic/bigint_elem_squared_tests.txt
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# ModSquare tests.
|
||||
#
|
||||
# These test vectors satisfy A * A = ModSquare (mod M) and 0 <= ModSquare < M.
|
||||
|
||||
# Regression test for CVE-2015-3193 (carry propagation bug in sqr8x_reduction).
|
||||
# XXX: It's pretty unclear if this is actually exercising the code that had the
|
||||
# bug. In fact it seems like it almost definitely isn't. This is here mostly
|
||||
# because it is convenient to add the test, and also to track the issue of the
|
||||
# lack of a real regression test. TODO: Fix this.
|
||||
ModSquare = 19324b647d967d644b3219
|
||||
A = 050505050505
|
||||
M = 414141414141414141414127414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||
|
||||
# Regression test for CVE-2017-3732.
|
||||
ModSquare = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001
|
||||
A = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff00000000
|
||||
M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff
|
||||
|
||||
ModSquare = 40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000145b09
|
||||
A = 8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000483
|
||||
M = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2645
|
||||
|
||||
# Regression test for CVE-2017-3736
|
||||
ModSquare = fe06fe0b06160c09
|
||||
A = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff00fcfdfc
|
||||
M = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8f800000000000010000000006c000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffff8f8f8f800000000000010000000006c000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffffffff
|
||||
13
zeroidc/vendor/ring/src/arithmetic/constant.rs
vendored
Normal file
13
zeroidc/vendor/ring/src/arithmetic/constant.rs
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
macro_rules! limbs {
|
||||
( $($limb:expr),+ ) => {
|
||||
[ $($limb),+ ]
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
macro_rules! limbs {
|
||||
( $($limb_lo:expr, $limb_hi:expr),+) => {
|
||||
[ $((($limb_hi | 0u64) << 32) | $limb_lo),+ ]
|
||||
};
|
||||
}
|
||||
88
zeroidc/vendor/ring/src/arithmetic/montgomery.rs
vendored
Normal file
88
zeroidc/vendor/ring/src/arithmetic/montgomery.rs
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2017 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// Indicates that the element is not encoded; there is no *R* factor
|
||||
// that needs to be canceled out.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Unencoded {}
|
||||
|
||||
// Indicates that the element is encoded; the value has one *R*
|
||||
// factor that needs to be canceled out.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum R {}
|
||||
|
||||
// Indicates the element is encoded twice; the value has two *R*
|
||||
// factors that need to be canceled out.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum RR {}
|
||||
|
||||
// Indicates the element is inversely encoded; the value has one
|
||||
// 1/*R* factor that needs to be canceled out.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum RInverse {}
|
||||
|
||||
pub trait Encoding {}
|
||||
|
||||
impl Encoding for RR {}
|
||||
impl Encoding for R {}
|
||||
impl Encoding for Unencoded {}
|
||||
impl Encoding for RInverse {}
|
||||
|
||||
/// The encoding of the result of a reduction.
|
||||
pub trait ReductionEncoding {
|
||||
type Output: Encoding;
|
||||
}
|
||||
|
||||
impl ReductionEncoding for RR {
|
||||
type Output = R;
|
||||
}
|
||||
impl ReductionEncoding for R {
|
||||
type Output = Unencoded;
|
||||
}
|
||||
impl ReductionEncoding for Unencoded {
|
||||
type Output = RInverse;
|
||||
}
|
||||
|
||||
/// The encoding of the result of a multiplication.
|
||||
pub trait ProductEncoding {
|
||||
type Output: Encoding;
|
||||
}
|
||||
|
||||
impl<E: ReductionEncoding> ProductEncoding for (Unencoded, E) {
|
||||
type Output = E::Output;
|
||||
}
|
||||
|
||||
impl<E: Encoding> ProductEncoding for (R, E) {
|
||||
type Output = E;
|
||||
}
|
||||
|
||||
impl<E: ReductionEncoding> ProductEncoding for (RInverse, E)
|
||||
where
|
||||
E::Output: ReductionEncoding,
|
||||
{
|
||||
type Output = <<E as ReductionEncoding>::Output as ReductionEncoding>::Output;
|
||||
}
|
||||
|
||||
// XXX: Rust doesn't allow overlapping impls,
|
||||
// TODO (if/when Rust allows it):
|
||||
// impl<E1, E2: ReductionEncoding> ProductEncoding for
|
||||
// (E1, E2) {
|
||||
// type Output = <(E2, E1) as ProductEncoding>::Output;
|
||||
// }
|
||||
impl ProductEncoding for (RR, Unencoded) {
|
||||
type Output = <(Unencoded, RR) as ProductEncoding>::Output;
|
||||
}
|
||||
impl ProductEncoding for (RR, RInverse) {
|
||||
type Output = <(RInverse, RR) as ProductEncoding>::Output;
|
||||
}
|
||||
64
zeroidc/vendor/ring/src/bits.rs
vendored
Normal file
64
zeroidc/vendor/ring/src/bits.rs
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use crate::error;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)]
|
||||
pub struct BitLength(usize);
|
||||
|
||||
// Lengths measured in bits, where all arithmetic is guaranteed not to
|
||||
// overflow.
|
||||
impl BitLength {
|
||||
#[inline]
|
||||
pub const fn from_usize_bits(bits: usize) -> Self {
|
||||
Self(bits)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_usize_bytes(bytes: usize) -> Result<Self, error::Unspecified> {
|
||||
let bits = bytes.checked_mul(8).ok_or(error::Unspecified)?;
|
||||
Ok(Self::from_usize_bits(bits))
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[inline]
|
||||
pub fn half_rounded_up(&self) -> Self {
|
||||
let round_up = self.0 & 1;
|
||||
Self((self.0 / 2) + round_up)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_usize_bits(&self) -> usize {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[inline]
|
||||
pub fn as_usize_bytes_rounded_up(&self) -> usize {
|
||||
// Equivalent to (self.0 + 7) / 8, except with no potential for
|
||||
// overflow and without branches.
|
||||
|
||||
// Branchless round_up = if self.0 & 0b111 != 0 { 1 } else { 0 };
|
||||
let round_up = ((self.0 >> 2) | (self.0 >> 1) | self.0) & 1;
|
||||
|
||||
(self.0 / 8) + round_up
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[inline]
|
||||
pub fn try_sub_1(self) -> Result<BitLength, error::Unspecified> {
|
||||
let sum = self.0.checked_sub(1).ok_or(error::Unspecified)?;
|
||||
Ok(BitLength(sum))
|
||||
}
|
||||
}
|
||||
59
zeroidc/vendor/ring/src/bssl.rs
vendored
Normal file
59
zeroidc/vendor/ring/src/bssl.rs
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2015 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use crate::{c, error};
|
||||
|
||||
/// An `int` returned from a foreign function containing **1** if the function
|
||||
/// was successful or **0** if an error occurred. This is the convention used by
|
||||
/// C code in `ring`.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[must_use]
|
||||
#[repr(transparent)]
|
||||
pub struct Result(c::int);
|
||||
|
||||
impl From<Result> for core::result::Result<(), error::Unspecified> {
|
||||
fn from(ret: Result) -> Self {
|
||||
match ret.0 {
|
||||
1 => Ok(()),
|
||||
c => {
|
||||
debug_assert_eq!(c, 0, "`bssl::Result` value must be 0 or 1");
|
||||
Err(error::Unspecified)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
mod result {
|
||||
use crate::{bssl, c};
|
||||
use core::mem;
|
||||
|
||||
#[test]
|
||||
fn size_and_alignment() {
|
||||
type Underlying = c::int;
|
||||
assert_eq!(mem::size_of::<bssl::Result>(), mem::size_of::<Underlying>());
|
||||
assert_eq!(
|
||||
mem::align_of::<bssl::Result>(),
|
||||
mem::align_of::<Underlying>()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn semantics() {
|
||||
assert!(Result::from(bssl::Result(0)).is_err());
|
||||
assert!(Result::from(bssl::Result(1)).is_ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
51
zeroidc/vendor/ring/src/c.rs
vendored
Normal file
51
zeroidc/vendor/ring/src/c.rs
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2016-2019 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! C types.
|
||||
//!
|
||||
//! Avoid using the `libc` crate to get C types since `libc` doesn't support
|
||||
//! all the targets we need to support. It turns out that the few types we need
|
||||
//! are all uniformly defined on the platforms we care about. This will
|
||||
//! probably change if/when we support 16-bit platforms or platforms where
|
||||
//! `usize` and `uintptr_t` are different sizes.
|
||||
|
||||
// Keep in sync with the checks in base.h that verify these assumptions.
|
||||
|
||||
pub(crate) type int = i32;
|
||||
pub(crate) type uint = u32;
|
||||
pub(crate) type size_t = usize;
|
||||
|
||||
#[cfg(all(test, any(unix, windows)))]
|
||||
mod tests {
|
||||
use crate::c;
|
||||
|
||||
#[test]
|
||||
fn test_libc_compatible() {
|
||||
{
|
||||
let x: c::int = 1;
|
||||
let _x: libc::c_int = x;
|
||||
}
|
||||
|
||||
{
|
||||
let x: c::uint = 1;
|
||||
let _x: libc::c_uint = x;
|
||||
}
|
||||
|
||||
{
|
||||
let x: c::size_t = 1;
|
||||
let _x: libc::size_t = x;
|
||||
let _x: usize = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
49
zeroidc/vendor/ring/src/constant_time.rs
vendored
Normal file
49
zeroidc/vendor/ring/src/constant_time.rs
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Constant-time operations.
|
||||
|
||||
use crate::{c, error};
|
||||
|
||||
/// Returns `Ok(())` if `a == b` and `Err(error::Unspecified)` otherwise.
|
||||
/// The comparison of `a` and `b` is done in constant time with respect to the
|
||||
/// contents of each, but NOT in constant time with respect to the lengths of
|
||||
/// `a` and `b`.
|
||||
pub fn verify_slices_are_equal(a: &[u8], b: &[u8]) -> Result<(), error::Unspecified> {
|
||||
if a.len() != b.len() {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
let result = unsafe { GFp_memcmp(a.as_ptr(), b.as_ptr(), a.len()) };
|
||||
match result {
|
||||
0 => Ok(()),
|
||||
_ => Err(error::Unspecified),
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn GFp_memcmp(a: *const u8, b: *const u8, len: c::size_t) -> c::int;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{bssl, error};
|
||||
|
||||
#[test]
|
||||
fn test_constant_time() -> Result<(), error::Unspecified> {
|
||||
extern "C" {
|
||||
fn bssl_constant_time_test_main() -> bssl::Result;
|
||||
}
|
||||
Result::from(unsafe { bssl_constant_time_test_main() })
|
||||
}
|
||||
}
|
||||
378
zeroidc/vendor/ring/src/cpu.rs
vendored
Normal file
378
zeroidc/vendor/ring/src/cpu.rs
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
/// A witness indicating that CPU features have been detected and cached.
|
||||
///
|
||||
/// TODO: Eventually all feature detection logic should be done through
|
||||
/// functions that accept a `Features` parameter, to guarantee that nothing
|
||||
/// tries to read the cached values before they are written.
|
||||
///
|
||||
/// This is a zero-sized type so that it can be "stored" wherever convenient.
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) struct Features(());
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn features() -> Features {
|
||||
// We don't do runtime feature detection on aarch64-apple-* as all AAarch64
|
||||
// features we use are available on every device since the first devices.
|
||||
#[cfg(any(
|
||||
target_arch = "x86",
|
||||
target_arch = "x86_64",
|
||||
all(
|
||||
any(target_arch = "aarch64", target_arch = "arm"),
|
||||
any(target_os = "android", target_os = "fuchsia", target_os = "linux")
|
||||
)
|
||||
))]
|
||||
{
|
||||
static INIT: spin::Once<()> = spin::Once::new();
|
||||
let () = INIT.call_once(|| {
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
{
|
||||
extern "C" {
|
||||
fn GFp_cpuid_setup();
|
||||
}
|
||||
unsafe {
|
||||
GFp_cpuid_setup();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(target_arch = "aarch64", target_arch = "arm"),
|
||||
any(target_os = "android", target_os = "fuchsia", target_os = "linux")
|
||||
))]
|
||||
{
|
||||
arm::setup();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Features(())
|
||||
}
|
||||
|
||||
pub(crate) mod arm {
|
||||
#[cfg(all(
|
||||
any(target_os = "android", target_os = "linux"),
|
||||
any(target_arch = "aarch64", target_arch = "arm")
|
||||
))]
|
||||
pub fn setup() {
|
||||
use libc::c_ulong;
|
||||
|
||||
// XXX: The `libc` crate doesn't provide `libc::getauxval` consistently
|
||||
// across all Android/Linux targets, e.g. musl.
|
||||
extern "C" {
|
||||
fn getauxval(type_: c_ulong) -> c_ulong;
|
||||
}
|
||||
|
||||
const AT_HWCAP: c_ulong = 16;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
const HWCAP_NEON: c_ulong = 1 << 1;
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
const HWCAP_NEON: c_ulong = 1 << 12;
|
||||
|
||||
let caps = unsafe { getauxval(AT_HWCAP) };
|
||||
|
||||
// We assume NEON is available on AARCH64 because it is a required
|
||||
// feature.
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
debug_assert!(caps & HWCAP_NEON == HWCAP_NEON);
|
||||
|
||||
// OpenSSL and BoringSSL don't enable any other features if NEON isn't
|
||||
// available.
|
||||
if caps & HWCAP_NEON == HWCAP_NEON {
|
||||
let mut features = NEON.mask;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
const OFFSET: c_ulong = 3;
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
const OFFSET: c_ulong = 0;
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
let caps = {
|
||||
const AT_HWCAP2: c_ulong = 26;
|
||||
unsafe { getauxval(AT_HWCAP2) }
|
||||
};
|
||||
|
||||
const HWCAP_AES: c_ulong = 1 << 0 + OFFSET;
|
||||
const HWCAP_PMULL: c_ulong = 1 << 1 + OFFSET;
|
||||
const HWCAP_SHA2: c_ulong = 1 << 3 + OFFSET;
|
||||
|
||||
if caps & HWCAP_AES == HWCAP_AES {
|
||||
features |= AES.mask;
|
||||
}
|
||||
if caps & HWCAP_PMULL == HWCAP_PMULL {
|
||||
features |= PMULL.mask;
|
||||
}
|
||||
if caps & HWCAP_SHA2 == HWCAP_SHA2 {
|
||||
features |= SHA256.mask;
|
||||
}
|
||||
|
||||
unsafe { GFp_armcap_P = features };
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "fuchsia", target_arch = "aarch64"))]
|
||||
pub fn setup() {
|
||||
type zx_status_t = i32;
|
||||
|
||||
#[link(name = "zircon")]
|
||||
extern "C" {
|
||||
fn zx_system_get_features(kind: u32, features: *mut u32) -> zx_status_t;
|
||||
}
|
||||
|
||||
const ZX_OK: i32 = 0;
|
||||
const ZX_FEATURE_KIND_CPU: u32 = 0;
|
||||
const ZX_ARM64_FEATURE_ISA_ASIMD: u32 = 1 << 2;
|
||||
const ZX_ARM64_FEATURE_ISA_AES: u32 = 1 << 3;
|
||||
const ZX_ARM64_FEATURE_ISA_PMULL: u32 = 1 << 4;
|
||||
const ZX_ARM64_FEATURE_ISA_SHA2: u32 = 1 << 6;
|
||||
|
||||
let mut caps = 0;
|
||||
let rc = unsafe { zx_system_get_features(ZX_FEATURE_KIND_CPU, &mut caps) };
|
||||
|
||||
// OpenSSL and BoringSSL don't enable any other features if NEON isn't
|
||||
// available.
|
||||
if rc == ZX_OK && (caps & ZX_ARM64_FEATURE_ISA_ASIMD == ZX_ARM64_FEATURE_ISA_ASIMD) {
|
||||
let mut features = NEON.mask;
|
||||
|
||||
if caps & ZX_ARM64_FEATURE_ISA_AES == ZX_ARM64_FEATURE_ISA_AES {
|
||||
features |= AES.mask;
|
||||
}
|
||||
if caps & ZX_ARM64_FEATURE_ISA_PMULL == ZX_ARM64_FEATURE_ISA_PMULL {
|
||||
features |= PMULL.mask;
|
||||
}
|
||||
if caps & ZX_ARM64_FEATURE_ISA_SHA2 == ZX_ARM64_FEATURE_ISA_SHA2 {
|
||||
features |= 1 << 4;
|
||||
}
|
||||
|
||||
unsafe { GFp_armcap_P = features };
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! features {
|
||||
{
|
||||
$(
|
||||
$name:ident {
|
||||
mask: $mask:expr,
|
||||
|
||||
/// Should we assume that the feature is always available
|
||||
/// for aarch64-apple-* targets? The first AArch64 iOS
|
||||
/// device used the Apple A7 chip.
|
||||
// TODO: When we can use `if` in const expressions:
|
||||
// ```
|
||||
// aarch64_apple: $aarch64_apple,
|
||||
// ```
|
||||
aarch64_apple: true,
|
||||
}
|
||||
),+
|
||||
, // trailing comma is required.
|
||||
} => {
|
||||
$(
|
||||
#[allow(dead_code)]
|
||||
pub(crate) const $name: Feature = Feature {
|
||||
mask: $mask,
|
||||
};
|
||||
)+
|
||||
|
||||
// TODO: When we can use `if` in const expressions, do this:
|
||||
// ```
|
||||
// const ARMCAP_STATIC: u32 = 0
|
||||
// $(
|
||||
// | ( if $aarch64_apple &&
|
||||
// cfg!(all(target_arch = "aarch64",
|
||||
// target_vendor = "apple")) {
|
||||
// $name.mask
|
||||
// } else {
|
||||
// 0
|
||||
// }
|
||||
// )
|
||||
// )+;
|
||||
// ```
|
||||
//
|
||||
// TODO: Add static feature detection to other targets.
|
||||
// TODO: Combine static feature detection with runtime feature
|
||||
// detection.
|
||||
#[cfg(all(target_arch = "aarch64", target_vendor = "apple"))]
|
||||
const ARMCAP_STATIC: u32 = 0
|
||||
$( | $name.mask
|
||||
)+;
|
||||
#[cfg(not(all(target_arch = "aarch64", target_vendor = "apple")))]
|
||||
const ARMCAP_STATIC: u32 = 0;
|
||||
|
||||
#[cfg(all(target_arch = "aarch64", target_vendor = "apple"))]
|
||||
#[test]
|
||||
fn test_armcap_static_available() {
|
||||
let features = crate::cpu::features();
|
||||
$(
|
||||
assert!($name.available(features));
|
||||
)+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) struct Feature {
|
||||
mask: u32,
|
||||
}
|
||||
|
||||
impl Feature {
|
||||
#[allow(dead_code)]
|
||||
#[inline(always)]
|
||||
pub fn available(&self, _: super::Features) -> bool {
|
||||
if self.mask == self.mask & ARMCAP_STATIC {
|
||||
return true;
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(target_os = "android", target_os = "fuchsia", target_os = "linux"),
|
||||
any(target_arch = "arm", target_arch = "aarch64")
|
||||
))]
|
||||
{
|
||||
if self.mask == self.mask & unsafe { GFp_armcap_P } {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
features! {
|
||||
// Keep in sync with `ARMV7_NEON`.
|
||||
NEON {
|
||||
mask: 1 << 0,
|
||||
aarch64_apple: true,
|
||||
},
|
||||
|
||||
// Keep in sync with `ARMV8_AES`.
|
||||
AES {
|
||||
mask: 1 << 2,
|
||||
aarch64_apple: true,
|
||||
},
|
||||
|
||||
// Keep in sync with `ARMV8_SHA256`.
|
||||
SHA256 {
|
||||
mask: 1 << 4,
|
||||
aarch64_apple: true,
|
||||
},
|
||||
|
||||
// Keep in sync with `ARMV8_PMULL`.
|
||||
PMULL {
|
||||
mask: 1 << 5,
|
||||
aarch64_apple: true,
|
||||
},
|
||||
}
|
||||
|
||||
// Some non-Rust code still checks this even when it is statically known
|
||||
// the given feature is available, so we have to ensure that this is
|
||||
// initialized properly. Keep this in sync with the initialization in
|
||||
// BoringSSL's crypto.c.
|
||||
//
|
||||
// TODO: This should have "hidden" visibility but we don't have a way of
|
||||
// controlling that yet: https://github.com/rust-lang/rust/issues/73958.
|
||||
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||
#[no_mangle]
|
||||
static mut GFp_armcap_P: u32 = ARMCAP_STATIC;
|
||||
|
||||
#[cfg(all(
|
||||
any(target_arch = "arm", target_arch = "aarch64"),
|
||||
target_vendor = "apple"
|
||||
))]
|
||||
#[test]
|
||||
fn test_armcap_static_matches_armcap_dynamic() {
|
||||
assert_eq!(ARMCAP_STATIC, 1 | 4 | 16 | 32);
|
||||
assert_eq!(ARMCAP_STATIC, unsafe { GFp_armcap_P });
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
not(any(target_arch = "x86", target_arch = "x86_64")),
|
||||
allow(dead_code)
|
||||
)]
|
||||
pub(crate) mod intel {
|
||||
pub(crate) struct Feature {
|
||||
word: usize,
|
||||
mask: u32,
|
||||
}
|
||||
|
||||
impl Feature {
|
||||
#[allow(clippy::needless_return)]
|
||||
#[inline(always)]
|
||||
pub fn available(&self, _: super::Features) -> bool {
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
{
|
||||
extern "C" {
|
||||
static mut GFp_ia32cap_P: [u32; 4];
|
||||
}
|
||||
return self.mask == self.mask & unsafe { GFp_ia32cap_P[self.word] };
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const FXSR: Feature = Feature {
|
||||
word: 0,
|
||||
mask: 1 << 24,
|
||||
};
|
||||
|
||||
pub(crate) const PCLMULQDQ: Feature = Feature {
|
||||
word: 1,
|
||||
mask: 1 << 1,
|
||||
};
|
||||
|
||||
pub(crate) const SSSE3: Feature = Feature {
|
||||
word: 1,
|
||||
mask: 1 << 9,
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub(crate) const SSE41: Feature = Feature {
|
||||
word: 1,
|
||||
mask: 1 << 19,
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub(crate) const MOVBE: Feature = Feature {
|
||||
word: 1,
|
||||
mask: 1 << 22,
|
||||
};
|
||||
|
||||
pub(crate) const AES: Feature = Feature {
|
||||
word: 1,
|
||||
mask: 1 << 25,
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub(crate) const AVX: Feature = Feature {
|
||||
word: 1,
|
||||
mask: 1 << 28,
|
||||
};
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", test))]
|
||||
mod x86_64_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_avx_movbe_mask() {
|
||||
// This is the OpenSSL style of testing these bits.
|
||||
assert_eq!((AVX.mask | MOVBE.mask) >> 22, 0x41);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
zeroidc/vendor/ring/src/data/alg-rsa-encryption.der
vendored
Normal file
BIN
zeroidc/vendor/ring/src/data/alg-rsa-encryption.der
vendored
Normal file
Binary file not shown.
84
zeroidc/vendor/ring/src/debug.rs
vendored
Normal file
84
zeroidc/vendor/ring/src/debug.rs
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2018 Trent Clarke.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// Generates an implementation of the Debug trait for a type that defers to the
|
||||
// Debug implementation for a given field.
|
||||
macro_rules! derive_debug_via_id {
|
||||
($typename:ident) => {
|
||||
impl ::core::fmt::Debug for $typename {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
|
||||
::core::fmt::Debug::fmt(&self.id, f)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! derive_debug_via_field {
|
||||
($type:ty, $field:ident) => {
|
||||
derive_debug_via_field!($type, stringify!($type), $field);
|
||||
};
|
||||
|
||||
($type:ty, $typename:expr, $field:ident) => {
|
||||
impl ::core::fmt::Debug for $type {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
|
||||
f.debug_struct($typename)
|
||||
.field(stringify!($field), &self.$field)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Generates an implementation of the Debug trait for a type that outputs the
|
||||
// hex encoding of the byte slice representation of the value.
|
||||
macro_rules! derive_debug_self_as_ref_hex_bytes {
|
||||
($typename:ident) => {
|
||||
impl ::core::fmt::Debug for $typename {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
|
||||
crate::debug::write_hex_tuple(f, stringify!($typename), self)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) fn write_hex_tuple(
|
||||
fmt: &mut core::fmt::Formatter,
|
||||
type_name: &str,
|
||||
value: &dyn AsRef<[u8]>,
|
||||
) -> Result<(), ::core::fmt::Error> {
|
||||
fmt.debug_tuple(type_name)
|
||||
.field(&HexStr(value.as_ref()))
|
||||
.finish()
|
||||
}
|
||||
|
||||
pub struct HexStr<'a>(pub &'a [u8]);
|
||||
|
||||
impl core::fmt::Debug for HexStr<'_> {
|
||||
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
fmt.write_str("\"")?;
|
||||
write_hex_bytes(fmt, self.0)?;
|
||||
fmt.write_str("\"")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write_hex_bytes(
|
||||
fmt: &mut core::fmt::Formatter,
|
||||
bytes: &[u8],
|
||||
) -> Result<(), ::core::fmt::Error> {
|
||||
for byte in bytes {
|
||||
write!(fmt, "{:02x}", byte)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
594
zeroidc/vendor/ring/src/digest.rs
vendored
Normal file
594
zeroidc/vendor/ring/src/digest.rs
vendored
Normal file
@@ -0,0 +1,594 @@
|
||||
// Copyright 2015-2019 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! SHA-2 and the legacy SHA-1 digest algorithm.
|
||||
//!
|
||||
//! If all the data is available in a single contiguous slice then the `digest`
|
||||
//! function should be used. Otherwise, the digest can be calculated in
|
||||
//! multiple steps using `Context`.
|
||||
|
||||
// Note on why are we doing things the hard way: It would be easy to implement
|
||||
// this using the C `EVP_MD`/`EVP_MD_CTX` interface. However, if we were to do
|
||||
// things that way, we'd have a hard dependency on `malloc` and other overhead.
|
||||
// The goal for this implementation is to drive the overhead as close to zero
|
||||
// as possible.
|
||||
|
||||
use crate::{
|
||||
c, cpu, debug,
|
||||
endian::{self, BigEndian},
|
||||
polyfill,
|
||||
};
|
||||
use core::num::Wrapping;
|
||||
|
||||
mod sha1;
|
||||
mod sha2;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct BlockContext {
|
||||
state: State,
|
||||
|
||||
// Note that SHA-512 has a 128-bit input bit counter, but this
|
||||
// implementation only supports up to 2^64-1 input bits for all algorithms,
|
||||
// so a 64-bit counter is more than sufficient.
|
||||
completed_data_blocks: u64,
|
||||
|
||||
/// The context's algorithm.
|
||||
pub algorithm: &'static Algorithm,
|
||||
|
||||
cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
impl BlockContext {
|
||||
pub(crate) fn new(algorithm: &'static Algorithm) -> Self {
|
||||
Self {
|
||||
state: algorithm.initial_state,
|
||||
completed_data_blocks: 0,
|
||||
algorithm,
|
||||
cpu_features: cpu::features(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn update(&mut self, input: &[u8]) {
|
||||
let num_blocks = input.len() / self.algorithm.block_len;
|
||||
assert_eq!(num_blocks * self.algorithm.block_len, input.len());
|
||||
if num_blocks > 0 {
|
||||
unsafe {
|
||||
(self.algorithm.block_data_order)(&mut self.state, input.as_ptr(), num_blocks);
|
||||
}
|
||||
self.completed_data_blocks = self
|
||||
.completed_data_blocks
|
||||
.checked_add(polyfill::u64_from_usize(num_blocks))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn finish(mut self, pending: &mut [u8], num_pending: usize) -> Digest {
|
||||
let block_len = self.algorithm.block_len;
|
||||
assert_eq!(pending.len(), block_len);
|
||||
assert!(num_pending <= pending.len());
|
||||
|
||||
let mut padding_pos = num_pending;
|
||||
pending[padding_pos] = 0x80;
|
||||
padding_pos += 1;
|
||||
|
||||
if padding_pos > block_len - self.algorithm.len_len {
|
||||
polyfill::slice::fill(&mut pending[padding_pos..block_len], 0);
|
||||
unsafe {
|
||||
(self.algorithm.block_data_order)(&mut self.state, pending.as_ptr(), 1);
|
||||
}
|
||||
// We don't increase |self.completed_data_blocks| because the
|
||||
// padding isn't data, and so it isn't included in the data length.
|
||||
padding_pos = 0;
|
||||
}
|
||||
|
||||
polyfill::slice::fill(&mut pending[padding_pos..(block_len - 8)], 0);
|
||||
|
||||
// Output the length, in bits, in big endian order.
|
||||
let completed_data_bits = self
|
||||
.completed_data_blocks
|
||||
.checked_mul(polyfill::u64_from_usize(block_len))
|
||||
.unwrap()
|
||||
.checked_add(polyfill::u64_from_usize(num_pending))
|
||||
.unwrap()
|
||||
.checked_mul(8)
|
||||
.unwrap();
|
||||
pending[(block_len - 8)..block_len].copy_from_slice(&u64::to_be_bytes(completed_data_bits));
|
||||
|
||||
unsafe {
|
||||
(self.algorithm.block_data_order)(&mut self.state, pending.as_ptr(), 1);
|
||||
}
|
||||
|
||||
Digest {
|
||||
algorithm: self.algorithm,
|
||||
value: (self.algorithm.format_output)(self.state),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A context for multi-step (Init-Update-Finish) digest calculations.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ring::digest;
|
||||
///
|
||||
/// let one_shot = digest::digest(&digest::SHA384, b"hello, world");
|
||||
///
|
||||
/// let mut ctx = digest::Context::new(&digest::SHA384);
|
||||
/// ctx.update(b"hello");
|
||||
/// ctx.update(b", ");
|
||||
/// ctx.update(b"world");
|
||||
/// let multi_part = ctx.finish();
|
||||
///
|
||||
/// assert_eq!(&one_shot.as_ref(), &multi_part.as_ref());
|
||||
/// ```
|
||||
#[derive(Clone)]
|
||||
pub struct Context {
|
||||
block: BlockContext,
|
||||
// TODO: More explicitly force 64-bit alignment for |pending|.
|
||||
pending: [u8; MAX_BLOCK_LEN],
|
||||
num_pending: usize,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Constructs a new context.
|
||||
pub fn new(algorithm: &'static Algorithm) -> Self {
|
||||
Self {
|
||||
block: BlockContext::new(algorithm),
|
||||
pending: [0u8; MAX_BLOCK_LEN],
|
||||
num_pending: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn clone_from(block: &BlockContext) -> Self {
|
||||
Self {
|
||||
block: block.clone(),
|
||||
pending: [0u8; MAX_BLOCK_LEN],
|
||||
num_pending: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the digest with all the data in `data`. `update` may be called
|
||||
/// zero or more times until `finish` is called. It must not be called
|
||||
/// after `finish` has been called.
|
||||
pub fn update(&mut self, data: &[u8]) {
|
||||
let block_len = self.block.algorithm.block_len;
|
||||
if data.len() < block_len - self.num_pending {
|
||||
self.pending[self.num_pending..(self.num_pending + data.len())].copy_from_slice(data);
|
||||
self.num_pending += data.len();
|
||||
return;
|
||||
}
|
||||
|
||||
let mut remaining = data;
|
||||
if self.num_pending > 0 {
|
||||
let to_copy = block_len - self.num_pending;
|
||||
self.pending[self.num_pending..block_len].copy_from_slice(&data[..to_copy]);
|
||||
self.block.update(&self.pending[..block_len]);
|
||||
remaining = &remaining[to_copy..];
|
||||
self.num_pending = 0;
|
||||
}
|
||||
|
||||
let num_blocks = remaining.len() / block_len;
|
||||
let num_to_save_for_later = remaining.len() % block_len;
|
||||
self.block.update(&remaining[..(num_blocks * block_len)]);
|
||||
if num_to_save_for_later > 0 {
|
||||
self.pending[..num_to_save_for_later]
|
||||
.copy_from_slice(&remaining[(remaining.len() - num_to_save_for_later)..]);
|
||||
self.num_pending = num_to_save_for_later;
|
||||
}
|
||||
}
|
||||
|
||||
/// Finalizes the digest calculation and returns the digest value. `finish`
|
||||
/// consumes the context so it cannot be (mis-)used after `finish` has been
|
||||
/// called.
|
||||
pub fn finish(mut self) -> Digest {
|
||||
let block_len = self.block.algorithm.block_len;
|
||||
self.block
|
||||
.finish(&mut self.pending[..block_len], self.num_pending)
|
||||
}
|
||||
|
||||
/// The algorithm that this context is using.
|
||||
#[inline(always)]
|
||||
pub fn algorithm(&self) -> &'static Algorithm {
|
||||
self.block.algorithm
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the digest of `data` using the given digest algorithm.
|
||||
///
|
||||
/// # Examples:
|
||||
///
|
||||
/// ```
|
||||
/// # #[cfg(feature = "alloc")]
|
||||
/// # {
|
||||
/// use ring::{digest, test};
|
||||
/// let expected_hex = "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b";
|
||||
/// let expected: Vec<u8> = test::from_hex(expected_hex).unwrap();
|
||||
/// let actual = digest::digest(&digest::SHA256, b"hello, world");
|
||||
///
|
||||
/// assert_eq!(&expected, &actual.as_ref());
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn digest(algorithm: &'static Algorithm, data: &[u8]) -> Digest {
|
||||
let mut ctx = Context::new(algorithm);
|
||||
ctx.update(data);
|
||||
ctx.finish()
|
||||
}
|
||||
|
||||
/// A calculated digest value.
|
||||
///
|
||||
/// Use `as_ref` to get the value as a `&[u8]`.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Digest {
|
||||
value: Output,
|
||||
algorithm: &'static Algorithm,
|
||||
}
|
||||
|
||||
impl Digest {
|
||||
/// The algorithm that was used to calculate the digest value.
|
||||
#[inline(always)]
|
||||
pub fn algorithm(&self) -> &'static Algorithm {
|
||||
self.algorithm
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for Digest {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
let as64 = unsafe { &self.value.as64 };
|
||||
&endian::as_byte_slice(as64)[..self.algorithm.output_len]
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for Digest {
|
||||
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(fmt, "{:?}:", self.algorithm)?;
|
||||
debug::write_hex_bytes(fmt, self.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// A digest algorithm.
|
||||
pub struct Algorithm {
|
||||
/// The length of a finalized digest.
|
||||
pub output_len: usize,
|
||||
|
||||
/// The size of the chaining value of the digest function, in bytes. For
|
||||
/// non-truncated algorithms (SHA-1, SHA-256, SHA-512), this is equal to
|
||||
/// `output_len`. For truncated algorithms (e.g. SHA-384, SHA-512/256),
|
||||
/// this is equal to the length before truncation. This is mostly helpful
|
||||
/// for determining the size of an HMAC key that is appropriate for the
|
||||
/// digest algorithm.
|
||||
pub chaining_len: usize,
|
||||
|
||||
/// The internal block length.
|
||||
pub block_len: usize,
|
||||
|
||||
/// The length of the length in the padding.
|
||||
len_len: usize,
|
||||
|
||||
block_data_order: unsafe extern "C" fn(state: &mut State, data: *const u8, num: c::size_t),
|
||||
format_output: fn(input: State) -> Output,
|
||||
|
||||
initial_state: State,
|
||||
|
||||
id: AlgorithmID,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum AlgorithmID {
|
||||
SHA1,
|
||||
SHA256,
|
||||
SHA384,
|
||||
SHA512,
|
||||
SHA512_256,
|
||||
}
|
||||
|
||||
impl PartialEq for Algorithm {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Algorithm {}
|
||||
|
||||
derive_debug_via_id!(Algorithm);
|
||||
|
||||
/// SHA-1 as specified in [FIPS 180-4]. Deprecated.
|
||||
///
|
||||
/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
||||
pub static SHA1_FOR_LEGACY_USE_ONLY: Algorithm = Algorithm {
|
||||
output_len: sha1::OUTPUT_LEN,
|
||||
chaining_len: sha1::CHAINING_LEN,
|
||||
block_len: sha1::BLOCK_LEN,
|
||||
len_len: 64 / 8,
|
||||
block_data_order: sha1::block_data_order,
|
||||
format_output: sha256_format_output,
|
||||
initial_state: State {
|
||||
as32: [
|
||||
Wrapping(0x67452301u32),
|
||||
Wrapping(0xefcdab89u32),
|
||||
Wrapping(0x98badcfeu32),
|
||||
Wrapping(0x10325476u32),
|
||||
Wrapping(0xc3d2e1f0u32),
|
||||
Wrapping(0),
|
||||
Wrapping(0),
|
||||
Wrapping(0),
|
||||
],
|
||||
},
|
||||
id: AlgorithmID::SHA1,
|
||||
};
|
||||
|
||||
/// SHA-256 as specified in [FIPS 180-4].
|
||||
///
|
||||
/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
||||
pub static SHA256: Algorithm = Algorithm {
|
||||
output_len: SHA256_OUTPUT_LEN,
|
||||
chaining_len: SHA256_OUTPUT_LEN,
|
||||
block_len: 512 / 8,
|
||||
len_len: 64 / 8,
|
||||
block_data_order: sha2::GFp_sha256_block_data_order,
|
||||
format_output: sha256_format_output,
|
||||
initial_state: State {
|
||||
as32: [
|
||||
Wrapping(0x6a09e667u32),
|
||||
Wrapping(0xbb67ae85u32),
|
||||
Wrapping(0x3c6ef372u32),
|
||||
Wrapping(0xa54ff53au32),
|
||||
Wrapping(0x510e527fu32),
|
||||
Wrapping(0x9b05688cu32),
|
||||
Wrapping(0x1f83d9abu32),
|
||||
Wrapping(0x5be0cd19u32),
|
||||
],
|
||||
},
|
||||
id: AlgorithmID::SHA256,
|
||||
};
|
||||
|
||||
/// SHA-384 as specified in [FIPS 180-4].
|
||||
///
|
||||
/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
||||
pub static SHA384: Algorithm = Algorithm {
|
||||
output_len: SHA384_OUTPUT_LEN,
|
||||
chaining_len: SHA512_OUTPUT_LEN,
|
||||
block_len: SHA512_BLOCK_LEN,
|
||||
len_len: SHA512_LEN_LEN,
|
||||
block_data_order: sha2::GFp_sha512_block_data_order,
|
||||
format_output: sha512_format_output,
|
||||
initial_state: State {
|
||||
as64: [
|
||||
Wrapping(0xcbbb9d5dc1059ed8),
|
||||
Wrapping(0x629a292a367cd507),
|
||||
Wrapping(0x9159015a3070dd17),
|
||||
Wrapping(0x152fecd8f70e5939),
|
||||
Wrapping(0x67332667ffc00b31),
|
||||
Wrapping(0x8eb44a8768581511),
|
||||
Wrapping(0xdb0c2e0d64f98fa7),
|
||||
Wrapping(0x47b5481dbefa4fa4),
|
||||
],
|
||||
},
|
||||
id: AlgorithmID::SHA384,
|
||||
};
|
||||
|
||||
/// SHA-512 as specified in [FIPS 180-4].
|
||||
///
|
||||
/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
||||
pub static SHA512: Algorithm = Algorithm {
|
||||
output_len: SHA512_OUTPUT_LEN,
|
||||
chaining_len: SHA512_OUTPUT_LEN,
|
||||
block_len: SHA512_BLOCK_LEN,
|
||||
len_len: SHA512_LEN_LEN,
|
||||
block_data_order: sha2::GFp_sha512_block_data_order,
|
||||
format_output: sha512_format_output,
|
||||
initial_state: State {
|
||||
as64: [
|
||||
Wrapping(0x6a09e667f3bcc908),
|
||||
Wrapping(0xbb67ae8584caa73b),
|
||||
Wrapping(0x3c6ef372fe94f82b),
|
||||
Wrapping(0xa54ff53a5f1d36f1),
|
||||
Wrapping(0x510e527fade682d1),
|
||||
Wrapping(0x9b05688c2b3e6c1f),
|
||||
Wrapping(0x1f83d9abfb41bd6b),
|
||||
Wrapping(0x5be0cd19137e2179),
|
||||
],
|
||||
},
|
||||
id: AlgorithmID::SHA512,
|
||||
};
|
||||
|
||||
/// SHA-512/256 as specified in [FIPS 180-4].
|
||||
///
|
||||
/// This is *not* the same as just truncating the output of SHA-512, as
|
||||
/// SHA-512/256 has its own initial state distinct from SHA-512's initial
|
||||
/// state.
|
||||
///
|
||||
/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
||||
pub static SHA512_256: Algorithm = Algorithm {
|
||||
output_len: SHA512_256_OUTPUT_LEN,
|
||||
chaining_len: SHA512_OUTPUT_LEN,
|
||||
block_len: SHA512_BLOCK_LEN,
|
||||
len_len: SHA512_LEN_LEN,
|
||||
block_data_order: sha2::GFp_sha512_block_data_order,
|
||||
format_output: sha512_format_output,
|
||||
initial_state: State {
|
||||
as64: [
|
||||
Wrapping(0x22312194fc2bf72c),
|
||||
Wrapping(0x9f555fa3c84c64c2),
|
||||
Wrapping(0x2393b86b6f53b151),
|
||||
Wrapping(0x963877195940eabd),
|
||||
Wrapping(0x96283ee2a88effe3),
|
||||
Wrapping(0xbe5e1e2553863992),
|
||||
Wrapping(0x2b0199fc2c85b8aa),
|
||||
Wrapping(0x0eb72ddc81c52ca2),
|
||||
],
|
||||
},
|
||||
id: AlgorithmID::SHA512_256,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)] // XXX: Why do we need to be `Copy`?
|
||||
#[repr(C)]
|
||||
union State {
|
||||
as64: [Wrapping<u64>; sha2::CHAINING_WORDS],
|
||||
as32: [Wrapping<u32>; sha2::CHAINING_WORDS],
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
union Output {
|
||||
as64: [BigEndian<u64>; 512 / 8 / core::mem::size_of::<BigEndian<u64>>()],
|
||||
as32: [BigEndian<u32>; 256 / 8 / core::mem::size_of::<BigEndian<u32>>()],
|
||||
}
|
||||
|
||||
/// The maximum block length (`Algorithm::block_len`) of all the algorithms in
|
||||
/// this module.
|
||||
pub const MAX_BLOCK_LEN: usize = 1024 / 8;
|
||||
|
||||
/// The maximum output length (`Algorithm::output_len`) of all the algorithms
|
||||
/// in this module.
|
||||
pub const MAX_OUTPUT_LEN: usize = 512 / 8;
|
||||
|
||||
/// The maximum chaining length (`Algorithm::chaining_len`) of all the
|
||||
/// algorithms in this module.
|
||||
pub const MAX_CHAINING_LEN: usize = MAX_OUTPUT_LEN;
|
||||
|
||||
fn sha256_format_output(input: State) -> Output {
|
||||
let input = unsafe { &input.as32 };
|
||||
Output {
|
||||
as32: [
|
||||
BigEndian::from(input[0]),
|
||||
BigEndian::from(input[1]),
|
||||
BigEndian::from(input[2]),
|
||||
BigEndian::from(input[3]),
|
||||
BigEndian::from(input[4]),
|
||||
BigEndian::from(input[5]),
|
||||
BigEndian::from(input[6]),
|
||||
BigEndian::from(input[7]),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
fn sha512_format_output(input: State) -> Output {
|
||||
let input = unsafe { &input.as64 };
|
||||
Output {
|
||||
as64: [
|
||||
BigEndian::from(input[0]),
|
||||
BigEndian::from(input[1]),
|
||||
BigEndian::from(input[2]),
|
||||
BigEndian::from(input[3]),
|
||||
BigEndian::from(input[4]),
|
||||
BigEndian::from(input[5]),
|
||||
BigEndian::from(input[6]),
|
||||
BigEndian::from(input[7]),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/// The length of the output of SHA-1, in bytes.
|
||||
pub const SHA1_OUTPUT_LEN: usize = sha1::OUTPUT_LEN;
|
||||
|
||||
/// The length of the output of SHA-256, in bytes.
|
||||
pub const SHA256_OUTPUT_LEN: usize = 256 / 8;
|
||||
|
||||
/// The length of the output of SHA-384, in bytes.
|
||||
pub const SHA384_OUTPUT_LEN: usize = 384 / 8;
|
||||
|
||||
/// The length of the output of SHA-512, in bytes.
|
||||
pub const SHA512_OUTPUT_LEN: usize = 512 / 8;
|
||||
|
||||
/// The length of the output of SHA-512/256, in bytes.
|
||||
pub const SHA512_256_OUTPUT_LEN: usize = 256 / 8;
|
||||
|
||||
/// The length of a block for SHA-512-based algorithms, in bytes.
|
||||
const SHA512_BLOCK_LEN: usize = 1024 / 8;
|
||||
|
||||
/// The length of the length field for SHA-512-based algorithms, in bytes.
|
||||
const SHA512_LEN_LEN: usize = 128 / 8;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
mod max_input {
|
||||
use super::super::super::digest;
|
||||
use crate::polyfill;
|
||||
use alloc::vec;
|
||||
|
||||
macro_rules! max_input_tests {
|
||||
( $algorithm_name:ident ) => {
|
||||
mod $algorithm_name {
|
||||
use super::super::super::super::digest;
|
||||
|
||||
#[test]
|
||||
fn max_input_test() {
|
||||
super::max_input_test(&digest::$algorithm_name);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn too_long_input_test_block() {
|
||||
super::too_long_input_test_block(&digest::$algorithm_name);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn too_long_input_test_byte() {
|
||||
super::too_long_input_test_byte(&digest::$algorithm_name);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn max_input_test(alg: &'static digest::Algorithm) {
|
||||
let mut context = nearly_full_context(alg);
|
||||
let next_input = vec![0u8; alg.block_len - 1];
|
||||
context.update(&next_input);
|
||||
let _ = context.finish(); // no panic
|
||||
}
|
||||
|
||||
fn too_long_input_test_block(alg: &'static digest::Algorithm) {
|
||||
let mut context = nearly_full_context(alg);
|
||||
let next_input = vec![0u8; alg.block_len];
|
||||
context.update(&next_input);
|
||||
let _ = context.finish(); // should panic
|
||||
}
|
||||
|
||||
fn too_long_input_test_byte(alg: &'static digest::Algorithm) {
|
||||
let mut context = nearly_full_context(alg);
|
||||
let next_input = vec![0u8; alg.block_len - 1];
|
||||
context.update(&next_input); // no panic
|
||||
context.update(&[0]);
|
||||
let _ = context.finish(); // should panic
|
||||
}
|
||||
|
||||
fn nearly_full_context(alg: &'static digest::Algorithm) -> digest::Context {
|
||||
// All implementations currently support up to 2^64-1 bits
|
||||
// of input; according to the spec, SHA-384 and SHA-512
|
||||
// support up to 2^128-1, but that's not implemented yet.
|
||||
let max_bytes = 1u64 << (64 - 3);
|
||||
let max_blocks = max_bytes / polyfill::u64_from_usize(alg.block_len);
|
||||
digest::Context {
|
||||
block: digest::BlockContext {
|
||||
state: alg.initial_state,
|
||||
completed_data_blocks: max_blocks - 1,
|
||||
algorithm: alg,
|
||||
cpu_features: crate::cpu::features(),
|
||||
},
|
||||
pending: [0u8; digest::MAX_BLOCK_LEN],
|
||||
num_pending: 0,
|
||||
}
|
||||
}
|
||||
|
||||
max_input_tests!(SHA1_FOR_LEGACY_USE_ONLY);
|
||||
max_input_tests!(SHA256);
|
||||
max_input_tests!(SHA384);
|
||||
max_input_tests!(SHA512);
|
||||
}
|
||||
}
|
||||
111
zeroidc/vendor/ring/src/digest/sha1.rs
vendored
Normal file
111
zeroidc/vendor/ring/src/digest/sha1.rs
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
// Copyright 2016 Simon Sapin.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::sha2::{ch, maj, Word};
|
||||
use crate::c;
|
||||
use core::{convert::TryInto, num::Wrapping};
|
||||
|
||||
pub const BLOCK_LEN: usize = 512 / 8;
|
||||
pub const CHAINING_LEN: usize = 160 / 8;
|
||||
pub const OUTPUT_LEN: usize = 160 / 8;
|
||||
const CHAINING_WORDS: usize = CHAINING_LEN / 4;
|
||||
|
||||
type W32 = Wrapping<u32>;
|
||||
|
||||
// FIPS 180-4 4.1.1
|
||||
#[inline]
|
||||
fn parity(x: W32, y: W32, z: W32) -> W32 {
|
||||
x ^ y ^ z
|
||||
}
|
||||
|
||||
type State = [W32; CHAINING_WORDS];
|
||||
const ROUNDS: usize = 80;
|
||||
|
||||
pub(super) extern "C" fn block_data_order(
|
||||
state: &mut super::State,
|
||||
data: *const u8,
|
||||
num: c::size_t,
|
||||
) {
|
||||
let state = unsafe { &mut state.as32 };
|
||||
let state: &mut State = (&mut state[..CHAINING_WORDS]).try_into().unwrap();
|
||||
let data = data as *const [<W32 as Word>::InputBytes; 16];
|
||||
let blocks = unsafe { core::slice::from_raw_parts(data, num) };
|
||||
*state = block_data_order_(*state, blocks)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[rustfmt::skip]
|
||||
fn block_data_order_(mut H: State, M: &[[<W32 as Word>::InputBytes; 16]]) -> State {
|
||||
for M in M {
|
||||
// FIPS 180-4 6.1.2 Step 1
|
||||
let mut W: [W32; ROUNDS] = [W32::ZERO; ROUNDS];
|
||||
for t in 0..16 {
|
||||
W[t] = W32::from_be_bytes(M[t]);
|
||||
}
|
||||
for t in 16..ROUNDS {
|
||||
let wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
|
||||
W[t] = rotl(wt, 1);
|
||||
}
|
||||
|
||||
// FIPS 180-4 6.1.2 Step 2
|
||||
let a = H[0];
|
||||
let b = H[1];
|
||||
let c = H[2];
|
||||
let d = H[3];
|
||||
let e = H[4];
|
||||
|
||||
// FIPS 180-4 6.1.2 Step 3 with constants and functions from FIPS 180-4 {4.1.1, 4.2.1}
|
||||
let (a, b, c, d, e) = step3(a, b, c, d, e, W[ 0..20].try_into().unwrap(), Wrapping(0x5a827999), ch);
|
||||
let (a, b, c, d, e) = step3(a, b, c, d, e, W[20..40].try_into().unwrap(), Wrapping(0x6ed9eba1), parity);
|
||||
let (a, b, c, d, e) = step3(a, b, c, d, e, W[40..60].try_into().unwrap(), Wrapping(0x8f1bbcdc), maj);
|
||||
let (a, b, c, d, e) = step3(a, b, c, d, e, W[60..80].try_into().unwrap(), Wrapping(0xca62c1d6), parity);
|
||||
|
||||
// FIPS 180-4 6.1.2 Step 4
|
||||
H[0] += a;
|
||||
H[1] += b;
|
||||
H[2] += c;
|
||||
H[3] += d;
|
||||
H[4] += e;
|
||||
}
|
||||
|
||||
H
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn step3(
|
||||
mut a: W32,
|
||||
mut b: W32,
|
||||
mut c: W32,
|
||||
mut d: W32,
|
||||
mut e: W32,
|
||||
W: [W32; 20],
|
||||
k: W32,
|
||||
f: impl Fn(W32, W32, W32) -> W32,
|
||||
) -> (W32, W32, W32, W32, W32) {
|
||||
for W_t in W.iter() {
|
||||
let T = rotl(a, 5) + f(b, c, d) + e + k + W_t;
|
||||
e = d;
|
||||
d = c;
|
||||
c = rotl(b, 30);
|
||||
b = a;
|
||||
a = T;
|
||||
}
|
||||
(a, b, c, d, e)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn rotl(x: W32, n: u32) -> W32 {
|
||||
Wrapping(x.0.rotate_left(n))
|
||||
}
|
||||
392
zeroidc/vendor/ring/src/digest/sha2.rs
vendored
Normal file
392
zeroidc/vendor/ring/src/digest/sha2.rs
vendored
Normal file
@@ -0,0 +1,392 @@
|
||||
// Copyright 2019 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use crate::c;
|
||||
use core::{
|
||||
num::Wrapping,
|
||||
ops::{Add, AddAssign, BitAnd, BitOr, BitXor, Not, Shr},
|
||||
};
|
||||
|
||||
#[cfg(not(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64")))]
|
||||
pub(super) extern "C" fn GFp_sha256_block_data_order(
|
||||
state: &mut super::State,
|
||||
data: *const u8,
|
||||
num: c::size_t,
|
||||
) {
|
||||
let state = unsafe { &mut state.as32 };
|
||||
*state = block_data_order(*state, data, num)
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64")))]
|
||||
pub(super) extern "C" fn GFp_sha512_block_data_order(
|
||||
state: &mut super::State,
|
||||
data: *const u8,
|
||||
num: c::size_t,
|
||||
) {
|
||||
let state = unsafe { &mut state.as64 };
|
||||
*state = block_data_order(*state, data, num)
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64"),
|
||||
allow(dead_code)
|
||||
)]
|
||||
#[inline]
|
||||
fn block_data_order<S: Sha2>(
|
||||
mut H: [S; CHAINING_WORDS],
|
||||
M: *const u8,
|
||||
num: c::size_t,
|
||||
) -> [S; CHAINING_WORDS] {
|
||||
let M = M as *const [S::InputBytes; 16];
|
||||
let M: &[[S::InputBytes; 16]] = unsafe { core::slice::from_raw_parts(M, num) };
|
||||
|
||||
for M in M {
|
||||
// FIPS 180-4 {6.2.2, 6.4.2} Step 1
|
||||
//
|
||||
// TODO: Use `let W: [S::ZERO; S::ROUNDS]` instead of allocating
|
||||
// `MAX_ROUNDS` items and then slicing to `K.len()`; depends on
|
||||
// https://github.com/rust-lang/rust/issues/43408.
|
||||
let mut W = [S::ZERO; MAX_ROUNDS];
|
||||
let W: &[S] = {
|
||||
let W = &mut W[..S::K.len()];
|
||||
for (W, M) in W.iter_mut().zip(M) {
|
||||
*W = S::from_be_bytes(*M);
|
||||
}
|
||||
for t in M.len()..S::K.len() {
|
||||
W[t] = sigma_1(W[t - 2]) + W[t - 7] + sigma_0(W[t - 15]) + W[t - 16]
|
||||
}
|
||||
|
||||
W
|
||||
};
|
||||
|
||||
// FIPS 180-4 {6.2.2, 6.4.2} Step 2
|
||||
let mut a = H[0];
|
||||
let mut b = H[1];
|
||||
let mut c = H[2];
|
||||
let mut d = H[3];
|
||||
let mut e = H[4];
|
||||
let mut f = H[5];
|
||||
let mut g = H[6];
|
||||
let mut h = H[7];
|
||||
|
||||
// FIPS 180-4 {6.2.2, 6.4.2} Step 3
|
||||
for (Kt, Wt) in S::K.iter().zip(W.iter()) {
|
||||
let T1 = h + SIGMA_1(e) + ch(e, f, g) + *Kt + *Wt;
|
||||
let T2 = SIGMA_0(a) + maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
}
|
||||
|
||||
// FIPS 180-4 {6.2.2, 6.4.2} Step 4
|
||||
H[0] += a;
|
||||
H[1] += b;
|
||||
H[2] += c;
|
||||
H[3] += d;
|
||||
H[4] += e;
|
||||
H[5] += f;
|
||||
H[6] += g;
|
||||
H[7] += h;
|
||||
}
|
||||
|
||||
H
|
||||
}
|
||||
|
||||
// FIPS 180-4 {4.1.1, 4.1.2, 4.1.3}
|
||||
#[inline(always)]
|
||||
pub(super) fn ch<W: Word>(x: W, y: W, z: W) -> W {
|
||||
(x & y) | (!x & z)
|
||||
}
|
||||
|
||||
// FIPS 180-4 {4.1.1, 4.1.2, 4.1.3}
|
||||
#[inline(always)]
|
||||
pub(super) fn maj<W: Word>(x: W, y: W, z: W) -> W {
|
||||
(x & y) | (x & z) | (y & z)
|
||||
}
|
||||
|
||||
// FIPS 180-4 {4.1.2, 4.1.3}
|
||||
#[inline(always)]
|
||||
fn SIGMA_0<S: Sha2>(x: S) -> S {
|
||||
x.rotr(S::BIG_SIGMA_0.0) ^ x.rotr(S::BIG_SIGMA_0.1) ^ x.rotr(S::BIG_SIGMA_0.2)
|
||||
}
|
||||
|
||||
// FIPS 180-4 {4.1.2, 4.1.3}
|
||||
#[inline(always)]
|
||||
fn SIGMA_1<S: Sha2>(x: S) -> S {
|
||||
x.rotr(S::BIG_SIGMA_1.0) ^ x.rotr(S::BIG_SIGMA_1.1) ^ x.rotr(S::BIG_SIGMA_1.2)
|
||||
}
|
||||
|
||||
// FIPS 180-4 {4.1.2, 4.1.3}
|
||||
#[inline(always)]
|
||||
fn sigma_0<S: Sha2>(x: S) -> S {
|
||||
x.rotr(S::SMALL_SIGMA_0.0) ^ x.rotr(S::SMALL_SIGMA_0.1) ^ (x >> S::SMALL_SIGMA_0.2)
|
||||
}
|
||||
|
||||
// FIPS 180-4 {4.1.2, 4.1.3}
|
||||
#[inline(always)]
|
||||
fn sigma_1<S: Sha2>(x: S) -> S {
|
||||
x.rotr(S::SMALL_SIGMA_1.0) ^ x.rotr(S::SMALL_SIGMA_1.1) ^ (x >> S::SMALL_SIGMA_1.2)
|
||||
}
|
||||
|
||||
// Commonality between SHA-1 and SHA-2 words.
|
||||
pub(super) trait Word:
|
||||
'static
|
||||
+ Sized
|
||||
+ Copy
|
||||
+ Add<Output = Self>
|
||||
+ AddAssign
|
||||
+ BitAnd<Output = Self>
|
||||
+ BitOr<Output = Self>
|
||||
+ Not<Output = Self>
|
||||
{
|
||||
const ZERO: Self;
|
||||
|
||||
type InputBytes: Copy;
|
||||
|
||||
fn from_be_bytes(input: Self::InputBytes) -> Self;
|
||||
|
||||
fn rotr(self, count: u32) -> Self;
|
||||
}
|
||||
|
||||
/// A SHA-2 input word.
|
||||
trait Sha2: Word + BitXor<Output = Self> + Shr<usize, Output = Self> {
|
||||
const BIG_SIGMA_0: (u32, u32, u32);
|
||||
const BIG_SIGMA_1: (u32, u32, u32);
|
||||
const SMALL_SIGMA_0: (u32, u32, usize);
|
||||
const SMALL_SIGMA_1: (u32, u32, usize);
|
||||
|
||||
const K: &'static [Self];
|
||||
}
|
||||
|
||||
const MAX_ROUNDS: usize = 80;
|
||||
pub(super) const CHAINING_WORDS: usize = 8;
|
||||
|
||||
impl Word for Wrapping<u32> {
|
||||
const ZERO: Self = Wrapping(0);
|
||||
type InputBytes = [u8; 4];
|
||||
|
||||
#[inline(always)]
|
||||
fn from_be_bytes(input: Self::InputBytes) -> Self {
|
||||
Wrapping(u32::from_be_bytes(input))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn rotr(self, count: u32) -> Self {
|
||||
Wrapping(self.0.rotate_right(count))
|
||||
}
|
||||
}
|
||||
|
||||
// SHA-256
|
||||
impl Sha2 for Wrapping<u32> {
|
||||
// FIPS 180-4 4.1.2
|
||||
const BIG_SIGMA_0: (u32, u32, u32) = (2, 13, 22);
|
||||
const BIG_SIGMA_1: (u32, u32, u32) = (6, 11, 25);
|
||||
const SMALL_SIGMA_0: (u32, u32, usize) = (7, 18, 3);
|
||||
const SMALL_SIGMA_1: (u32, u32, usize) = (17, 19, 10);
|
||||
|
||||
// FIPS 180-4 4.2.2
|
||||
const K: &'static [Self] = &[
|
||||
Self(0x428a2f98),
|
||||
Self(0x71374491),
|
||||
Self(0xb5c0fbcf),
|
||||
Self(0xe9b5dba5),
|
||||
Self(0x3956c25b),
|
||||
Self(0x59f111f1),
|
||||
Self(0x923f82a4),
|
||||
Self(0xab1c5ed5),
|
||||
Self(0xd807aa98),
|
||||
Self(0x12835b01),
|
||||
Self(0x243185be),
|
||||
Self(0x550c7dc3),
|
||||
Self(0x72be5d74),
|
||||
Self(0x80deb1fe),
|
||||
Self(0x9bdc06a7),
|
||||
Self(0xc19bf174),
|
||||
Self(0xe49b69c1),
|
||||
Self(0xefbe4786),
|
||||
Self(0x0fc19dc6),
|
||||
Self(0x240ca1cc),
|
||||
Self(0x2de92c6f),
|
||||
Self(0x4a7484aa),
|
||||
Self(0x5cb0a9dc),
|
||||
Self(0x76f988da),
|
||||
Self(0x983e5152),
|
||||
Self(0xa831c66d),
|
||||
Self(0xb00327c8),
|
||||
Self(0xbf597fc7),
|
||||
Self(0xc6e00bf3),
|
||||
Self(0xd5a79147),
|
||||
Self(0x06ca6351),
|
||||
Self(0x14292967),
|
||||
Self(0x27b70a85),
|
||||
Self(0x2e1b2138),
|
||||
Self(0x4d2c6dfc),
|
||||
Self(0x53380d13),
|
||||
Self(0x650a7354),
|
||||
Self(0x766a0abb),
|
||||
Self(0x81c2c92e),
|
||||
Self(0x92722c85),
|
||||
Self(0xa2bfe8a1),
|
||||
Self(0xa81a664b),
|
||||
Self(0xc24b8b70),
|
||||
Self(0xc76c51a3),
|
||||
Self(0xd192e819),
|
||||
Self(0xd6990624),
|
||||
Self(0xf40e3585),
|
||||
Self(0x106aa070),
|
||||
Self(0x19a4c116),
|
||||
Self(0x1e376c08),
|
||||
Self(0x2748774c),
|
||||
Self(0x34b0bcb5),
|
||||
Self(0x391c0cb3),
|
||||
Self(0x4ed8aa4a),
|
||||
Self(0x5b9cca4f),
|
||||
Self(0x682e6ff3),
|
||||
Self(0x748f82ee),
|
||||
Self(0x78a5636f),
|
||||
Self(0x84c87814),
|
||||
Self(0x8cc70208),
|
||||
Self(0x90befffa),
|
||||
Self(0xa4506ceb),
|
||||
Self(0xbef9a3f7),
|
||||
Self(0xc67178f2),
|
||||
];
|
||||
}
|
||||
|
||||
impl Word for Wrapping<u64> {
|
||||
const ZERO: Self = Wrapping(0);
|
||||
type InputBytes = [u8; 8];
|
||||
|
||||
#[inline(always)]
|
||||
fn from_be_bytes(input: Self::InputBytes) -> Self {
|
||||
Wrapping(u64::from_be_bytes(input))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn rotr(self, count: u32) -> Self {
|
||||
Wrapping(self.0.rotate_right(count))
|
||||
}
|
||||
}
|
||||
|
||||
// SHA-384 and SHA-512
|
||||
impl Sha2 for Wrapping<u64> {
|
||||
// FIPS 180-4 4.1.3
|
||||
const BIG_SIGMA_0: (u32, u32, u32) = (28, 34, 39);
|
||||
const BIG_SIGMA_1: (u32, u32, u32) = (14, 18, 41);
|
||||
const SMALL_SIGMA_0: (u32, u32, usize) = (1, 8, 7);
|
||||
const SMALL_SIGMA_1: (u32, u32, usize) = (19, 61, 6);
|
||||
|
||||
// FIPS 180-4 4.2.3
|
||||
const K: &'static [Self] = &[
|
||||
Self(0x428a2f98d728ae22),
|
||||
Self(0x7137449123ef65cd),
|
||||
Self(0xb5c0fbcfec4d3b2f),
|
||||
Self(0xe9b5dba58189dbbc),
|
||||
Self(0x3956c25bf348b538),
|
||||
Self(0x59f111f1b605d019),
|
||||
Self(0x923f82a4af194f9b),
|
||||
Self(0xab1c5ed5da6d8118),
|
||||
Self(0xd807aa98a3030242),
|
||||
Self(0x12835b0145706fbe),
|
||||
Self(0x243185be4ee4b28c),
|
||||
Self(0x550c7dc3d5ffb4e2),
|
||||
Self(0x72be5d74f27b896f),
|
||||
Self(0x80deb1fe3b1696b1),
|
||||
Self(0x9bdc06a725c71235),
|
||||
Self(0xc19bf174cf692694),
|
||||
Self(0xe49b69c19ef14ad2),
|
||||
Self(0xefbe4786384f25e3),
|
||||
Self(0x0fc19dc68b8cd5b5),
|
||||
Self(0x240ca1cc77ac9c65),
|
||||
Self(0x2de92c6f592b0275),
|
||||
Self(0x4a7484aa6ea6e483),
|
||||
Self(0x5cb0a9dcbd41fbd4),
|
||||
Self(0x76f988da831153b5),
|
||||
Self(0x983e5152ee66dfab),
|
||||
Self(0xa831c66d2db43210),
|
||||
Self(0xb00327c898fb213f),
|
||||
Self(0xbf597fc7beef0ee4),
|
||||
Self(0xc6e00bf33da88fc2),
|
||||
Self(0xd5a79147930aa725),
|
||||
Self(0x06ca6351e003826f),
|
||||
Self(0x142929670a0e6e70),
|
||||
Self(0x27b70a8546d22ffc),
|
||||
Self(0x2e1b21385c26c926),
|
||||
Self(0x4d2c6dfc5ac42aed),
|
||||
Self(0x53380d139d95b3df),
|
||||
Self(0x650a73548baf63de),
|
||||
Self(0x766a0abb3c77b2a8),
|
||||
Self(0x81c2c92e47edaee6),
|
||||
Self(0x92722c851482353b),
|
||||
Self(0xa2bfe8a14cf10364),
|
||||
Self(0xa81a664bbc423001),
|
||||
Self(0xc24b8b70d0f89791),
|
||||
Self(0xc76c51a30654be30),
|
||||
Self(0xd192e819d6ef5218),
|
||||
Self(0xd69906245565a910),
|
||||
Self(0xf40e35855771202a),
|
||||
Self(0x106aa07032bbd1b8),
|
||||
Self(0x19a4c116b8d2d0c8),
|
||||
Self(0x1e376c085141ab53),
|
||||
Self(0x2748774cdf8eeb99),
|
||||
Self(0x34b0bcb5e19b48a8),
|
||||
Self(0x391c0cb3c5c95a63),
|
||||
Self(0x4ed8aa4ae3418acb),
|
||||
Self(0x5b9cca4f7763e373),
|
||||
Self(0x682e6ff3d6b2b8a3),
|
||||
Self(0x748f82ee5defb2fc),
|
||||
Self(0x78a5636f43172f60),
|
||||
Self(0x84c87814a1f0ab72),
|
||||
Self(0x8cc702081a6439ec),
|
||||
Self(0x90befffa23631e28),
|
||||
Self(0xa4506cebde82bde9),
|
||||
Self(0xbef9a3f7b2c67915),
|
||||
Self(0xc67178f2e372532b),
|
||||
Self(0xca273eceea26619c),
|
||||
Self(0xd186b8c721c0c207),
|
||||
Self(0xeada7dd6cde0eb1e),
|
||||
Self(0xf57d4f7fee6ed178),
|
||||
Self(0x06f067aa72176fba),
|
||||
Self(0x0a637dc5a2c898a6),
|
||||
Self(0x113f9804bef90dae),
|
||||
Self(0x1b710b35131c471b),
|
||||
Self(0x28db77f523047d84),
|
||||
Self(0x32caab7b40c72493),
|
||||
Self(0x3c9ebe0a15c9bebc),
|
||||
Self(0x431d67c49c100d4c),
|
||||
Self(0x4cc5d4becb3e42b6),
|
||||
Self(0x597f299cfc657e2a),
|
||||
Self(0x5fcb6fab3ad6faec),
|
||||
Self(0x6c44198c4a475817),
|
||||
];
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64"))]
|
||||
extern "C" {
|
||||
pub(super) fn GFp_sha256_block_data_order(
|
||||
state: &mut super::State,
|
||||
data: *const u8,
|
||||
num: c::size_t,
|
||||
);
|
||||
pub(super) fn GFp_sha512_block_data_order(
|
||||
state: &mut super::State,
|
||||
data: *const u8,
|
||||
num: c::size_t,
|
||||
);
|
||||
}
|
||||
62
zeroidc/vendor/ring/src/ec.rs
vendored
Normal file
62
zeroidc/vendor/ring/src/ec.rs
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2015-2017 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use crate::{error, rand};
|
||||
|
||||
pub use self::keys::{KeyPair, PublicKey, Seed};
|
||||
|
||||
pub struct Curve {
|
||||
pub public_key_len: usize,
|
||||
pub elem_scalar_seed_len: usize,
|
||||
|
||||
pub id: CurveID,
|
||||
|
||||
// Precondition: `bytes` is the correct length.
|
||||
check_private_key_bytes: fn(bytes: &[u8]) -> Result<(), error::Unspecified>,
|
||||
|
||||
generate_private_key:
|
||||
fn(rng: &dyn rand::SecureRandom, &mut [u8]) -> Result<(), error::Unspecified>,
|
||||
|
||||
public_from_private:
|
||||
fn(public_out: &mut [u8], private_key: &Seed) -> Result<(), error::Unspecified>,
|
||||
}
|
||||
|
||||
derive_debug_via_id!(Curve);
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum CurveID {
|
||||
Curve25519,
|
||||
P256,
|
||||
P384,
|
||||
}
|
||||
|
||||
const ELEM_MAX_BITS: usize = 384;
|
||||
pub const ELEM_MAX_BYTES: usize = (ELEM_MAX_BITS + 7) / 8;
|
||||
|
||||
pub const SCALAR_MAX_BYTES: usize = ELEM_MAX_BYTES;
|
||||
const SEED_MAX_BYTES: usize = ELEM_MAX_BYTES;
|
||||
|
||||
/// The maximum length of a PKCS#8 documents generated by *ring* for ECC keys.
|
||||
///
|
||||
/// This is NOT the maximum length of a PKCS#8 document that can be consumed by
|
||||
/// `pkcs8::unwrap_key()`.
|
||||
///
|
||||
/// `40` is the length of the P-384 template. It is actually one byte shorter
|
||||
/// than the P-256 template, but the private key and the public key are much
|
||||
/// longer.
|
||||
pub const PKCS8_DOCUMENT_MAX_LEN: usize = 40 + SCALAR_MAX_BYTES + keys::PUBLIC_KEY_MAX_LEN;
|
||||
|
||||
pub mod curve25519;
|
||||
mod keys;
|
||||
pub mod suite_b;
|
||||
21
zeroidc/vendor/ring/src/ec/curve25519.rs
vendored
Normal file
21
zeroidc/vendor/ring/src/ec/curve25519.rs
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Elliptic curve operations and schemes using Curve25519.
|
||||
|
||||
pub mod ed25519;
|
||||
pub mod x25519;
|
||||
|
||||
mod ops;
|
||||
mod scalar;
|
||||
32
zeroidc/vendor/ring/src/ec/curve25519/ed25519.rs
vendored
Normal file
32
zeroidc/vendor/ring/src/ec/curve25519/ed25519.rs
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! EdDSA Signatures.
|
||||
|
||||
use super::ops::ELEM_LEN;
|
||||
use crate::digest;
|
||||
|
||||
pub mod signing;
|
||||
pub mod verification;
|
||||
|
||||
/// The length of an Ed25519 public key.
|
||||
pub const ED25519_PUBLIC_KEY_LEN: usize = ELEM_LEN;
|
||||
|
||||
pub fn eddsa_digest(signature_r: &[u8], public_key: &[u8], msg: &[u8]) -> digest::Digest {
|
||||
let mut ctx = digest::Context::new(&digest::SHA512);
|
||||
ctx.update(signature_r);
|
||||
ctx.update(public_key);
|
||||
ctx.update(msg);
|
||||
ctx.finish()
|
||||
}
|
||||
BIN
zeroidc/vendor/ring/src/ec/curve25519/ed25519/ed25519_pkcs8_v2_template.der
vendored
Normal file
BIN
zeroidc/vendor/ring/src/ec/curve25519/ed25519/ed25519_pkcs8_v2_template.der
vendored
Normal file
Binary file not shown.
270
zeroidc/vendor/ring/src/ec/curve25519/ed25519/signing.rs
vendored
Normal file
270
zeroidc/vendor/ring/src/ec/curve25519/ed25519/signing.rs
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! EdDSA Signatures.
|
||||
|
||||
use super::{super::ops::*, eddsa_digest, ED25519_PUBLIC_KEY_LEN};
|
||||
use crate::{
|
||||
digest, error,
|
||||
io::der,
|
||||
pkcs8, rand,
|
||||
signature::{self, KeyPair as SigningKeyPair},
|
||||
};
|
||||
use core::convert::TryInto;
|
||||
|
||||
/// An Ed25519 key pair, for signing.
|
||||
pub struct Ed25519KeyPair {
|
||||
// RFC 8032 Section 5.1.6 calls this *s*.
|
||||
private_scalar: Scalar,
|
||||
|
||||
// RFC 8032 Section 5.1.6 calls this *prefix*.
|
||||
private_prefix: Prefix,
|
||||
|
||||
// RFC 8032 Section 5.1.5 calls this *A*.
|
||||
public_key: PublicKey,
|
||||
}
|
||||
|
||||
derive_debug_via_field!(Ed25519KeyPair, stringify!(Ed25519KeyPair), public_key);
|
||||
|
||||
impl Ed25519KeyPair {
|
||||
/// Generates a new key pair and returns the key pair serialized as a
|
||||
/// PKCS#8 document.
|
||||
///
|
||||
/// The PKCS#8 document will be a v2 `OneAsymmetricKey` with the public key,
|
||||
/// as described in [RFC 5958 Section 2]; see [RFC 8410 Section 10.3] for an
|
||||
/// example.
|
||||
///
|
||||
/// [RFC 5958 Section 2]: https://tools.ietf.org/html/rfc5958#section-2
|
||||
/// [RFC 8410 Section 10.3]: https://tools.ietf.org/html/rfc8410#section-10.3
|
||||
pub fn generate_pkcs8(
|
||||
rng: &dyn rand::SecureRandom,
|
||||
) -> Result<pkcs8::Document, error::Unspecified> {
|
||||
let seed: [u8; SEED_LEN] = rand::generate(rng)?.expose();
|
||||
let key_pair = Self::from_seed_(&seed);
|
||||
Ok(pkcs8::wrap_key(
|
||||
&PKCS8_TEMPLATE,
|
||||
&seed[..],
|
||||
key_pair.public_key().as_ref(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Constructs an Ed25519 key pair by parsing an unencrypted PKCS#8 v2
|
||||
/// Ed25519 private key.
|
||||
///
|
||||
/// `openssl genpkey -algorithm ED25519` generates PKCS# v1 keys, which
|
||||
/// require the use of `Ed25519KeyPair::from_pkcs8_maybe_unchecked()`
|
||||
/// instead of `Ed25519KeyPair::from_pkcs8()`.
|
||||
///
|
||||
/// The input must be in PKCS#8 v2 format, and in particular it must contain
|
||||
/// the public key in addition to the private key. `from_pkcs8()` will
|
||||
/// verify that the public key and the private key are consistent with each
|
||||
/// other.
|
||||
///
|
||||
/// If you need to parse PKCS#8 v1 files (without the public key) then use
|
||||
/// `Ed25519KeyPair::from_pkcs8_maybe_unchecked()` instead.
|
||||
pub fn from_pkcs8(pkcs8: &[u8]) -> Result<Self, error::KeyRejected> {
|
||||
let (seed, public_key) =
|
||||
unwrap_pkcs8(pkcs8::Version::V2Only, untrusted::Input::from(pkcs8))?;
|
||||
Self::from_seed_and_public_key(
|
||||
seed.as_slice_less_safe(),
|
||||
public_key.unwrap().as_slice_less_safe(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Constructs an Ed25519 key pair by parsing an unencrypted PKCS#8 v1 or v2
|
||||
/// Ed25519 private key.
|
||||
///
|
||||
/// `openssl genpkey -algorithm ED25519` generates PKCS# v1 keys.
|
||||
///
|
||||
/// It is recommended to use `Ed25519KeyPair::from_pkcs8()`, which accepts
|
||||
/// only PKCS#8 v2 files that contain the public key.
|
||||
/// `from_pkcs8_maybe_unchecked()` parses PKCS#2 files exactly like
|
||||
/// `from_pkcs8()`. It also accepts v1 files. PKCS#8 v1 files do not contain
|
||||
/// the public key, so when a v1 file is parsed the public key will be
|
||||
/// computed from the private key, and there will be no consistency check
|
||||
/// between the public key and the private key.
|
||||
///
|
||||
/// PKCS#8 v2 files are parsed exactly like `Ed25519KeyPair::from_pkcs8()`.
|
||||
pub fn from_pkcs8_maybe_unchecked(pkcs8: &[u8]) -> Result<Self, error::KeyRejected> {
|
||||
let (seed, public_key) =
|
||||
unwrap_pkcs8(pkcs8::Version::V1OrV2, untrusted::Input::from(pkcs8))?;
|
||||
if let Some(public_key) = public_key {
|
||||
Self::from_seed_and_public_key(
|
||||
seed.as_slice_less_safe(),
|
||||
public_key.as_slice_less_safe(),
|
||||
)
|
||||
} else {
|
||||
Self::from_seed_unchecked(seed.as_slice_less_safe())
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs an Ed25519 key pair from the private key seed `seed` and its
|
||||
/// public key `public_key`.
|
||||
///
|
||||
/// It is recommended to use `Ed25519KeyPair::from_pkcs8()` instead.
|
||||
///
|
||||
/// The private and public keys will be verified to be consistent with each
|
||||
/// other. This helps avoid misuse of the key (e.g. accidentally swapping
|
||||
/// the private key and public key, or using the wrong private key for the
|
||||
/// public key). This also detects any corruption of the public or private
|
||||
/// key.
|
||||
pub fn from_seed_and_public_key(
|
||||
seed: &[u8],
|
||||
public_key: &[u8],
|
||||
) -> Result<Self, error::KeyRejected> {
|
||||
let pair = Self::from_seed_unchecked(seed)?;
|
||||
|
||||
// This implicitly verifies that `public_key` is the right length.
|
||||
// XXX: This rejects ~18 keys when they are partially reduced, though
|
||||
// those keys are virtually impossible to find.
|
||||
if public_key != pair.public_key.as_ref() {
|
||||
let err = if public_key.len() != pair.public_key.as_ref().len() {
|
||||
error::KeyRejected::invalid_encoding()
|
||||
} else {
|
||||
error::KeyRejected::inconsistent_components()
|
||||
};
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
Ok(pair)
|
||||
}
|
||||
|
||||
/// Constructs a Ed25519 key pair from the private key seed `seed`.
|
||||
///
|
||||
/// It is recommended to use `Ed25519KeyPair::from_pkcs8()` instead. When
|
||||
/// that is not practical, it is recommended to use
|
||||
/// `Ed25519KeyPair::from_seed_and_public_key()` instead.
|
||||
///
|
||||
/// Since the public key is not given, the public key will be computed from
|
||||
/// the private key. It is not possible to detect misuse or corruption of
|
||||
/// the private key since the public key isn't given as input.
|
||||
pub fn from_seed_unchecked(seed: &[u8]) -> Result<Self, error::KeyRejected> {
|
||||
let seed = seed
|
||||
.try_into()
|
||||
.map_err(|_| error::KeyRejected::invalid_encoding())?;
|
||||
Ok(Self::from_seed_(seed))
|
||||
}
|
||||
|
||||
fn from_seed_(seed: &Seed) -> Self {
|
||||
let h = digest::digest(&digest::SHA512, seed);
|
||||
let (private_scalar, private_prefix) = h.as_ref().split_at(SCALAR_LEN);
|
||||
|
||||
let private_scalar =
|
||||
MaskedScalar::from_bytes_masked(private_scalar.try_into().unwrap()).into();
|
||||
|
||||
let mut a = ExtPoint::new_at_infinity();
|
||||
unsafe {
|
||||
GFp_x25519_ge_scalarmult_base(&mut a, &private_scalar);
|
||||
}
|
||||
|
||||
Self {
|
||||
private_scalar,
|
||||
private_prefix: private_prefix.try_into().unwrap(),
|
||||
public_key: PublicKey(a.into_encoded_point()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the signature of the message `msg`.
|
||||
pub fn sign(&self, msg: &[u8]) -> signature::Signature {
|
||||
signature::Signature::new(|signature_bytes| {
|
||||
extern "C" {
|
||||
fn GFp_x25519_sc_muladd(
|
||||
s: &mut [u8; SCALAR_LEN],
|
||||
a: &Scalar,
|
||||
b: &Scalar,
|
||||
c: &Scalar,
|
||||
);
|
||||
}
|
||||
|
||||
let (signature_bytes, _unused) = signature_bytes.split_at_mut(ELEM_LEN + SCALAR_LEN);
|
||||
let (signature_r, signature_s) = signature_bytes.split_at_mut(ELEM_LEN);
|
||||
let nonce = {
|
||||
let mut ctx = digest::Context::new(&digest::SHA512);
|
||||
ctx.update(&self.private_prefix);
|
||||
ctx.update(msg);
|
||||
ctx.finish()
|
||||
};
|
||||
let nonce = Scalar::from_sha512_digest_reduced(nonce);
|
||||
|
||||
let mut r = ExtPoint::new_at_infinity();
|
||||
unsafe {
|
||||
GFp_x25519_ge_scalarmult_base(&mut r, &nonce);
|
||||
}
|
||||
signature_r.copy_from_slice(&r.into_encoded_point());
|
||||
let hram_digest = eddsa_digest(signature_r, &self.public_key.as_ref(), msg);
|
||||
let hram = Scalar::from_sha512_digest_reduced(hram_digest);
|
||||
unsafe {
|
||||
GFp_x25519_sc_muladd(
|
||||
signature_s.try_into().unwrap(),
|
||||
&hram,
|
||||
&self.private_scalar,
|
||||
&nonce,
|
||||
);
|
||||
}
|
||||
|
||||
SIGNATURE_LEN
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl signature::KeyPair for Ed25519KeyPair {
|
||||
type PublicKey = PublicKey;
|
||||
|
||||
fn public_key(&self) -> &Self::PublicKey {
|
||||
&self.public_key
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PublicKey([u8; ED25519_PUBLIC_KEY_LEN]);
|
||||
|
||||
impl AsRef<[u8]> for PublicKey {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
derive_debug_self_as_ref_hex_bytes!(PublicKey);
|
||||
|
||||
fn unwrap_pkcs8(
|
||||
version: pkcs8::Version,
|
||||
input: untrusted::Input,
|
||||
) -> Result<(untrusted::Input, Option<untrusted::Input>), error::KeyRejected> {
|
||||
let (private_key, public_key) = pkcs8::unwrap_key(&PKCS8_TEMPLATE, version, input)?;
|
||||
let private_key = private_key
|
||||
.read_all(error::Unspecified, |input| {
|
||||
der::expect_tag_and_get_value(input, der::Tag::OctetString)
|
||||
})
|
||||
.map_err(|error::Unspecified| error::KeyRejected::invalid_encoding())?;
|
||||
Ok((private_key, public_key))
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn GFp_x25519_ge_scalarmult_base(h: &mut ExtPoint, a: &Scalar);
|
||||
}
|
||||
|
||||
type Prefix = [u8; PREFIX_LEN];
|
||||
const PREFIX_LEN: usize = digest::SHA512_OUTPUT_LEN - SCALAR_LEN;
|
||||
|
||||
const SIGNATURE_LEN: usize = ELEM_LEN + SCALAR_LEN;
|
||||
|
||||
type Seed = [u8; SEED_LEN];
|
||||
const SEED_LEN: usize = 32;
|
||||
|
||||
static PKCS8_TEMPLATE: pkcs8::Template = pkcs8::Template {
|
||||
bytes: include_bytes!("ed25519_pkcs8_v2_template.der"),
|
||||
alg_id_range: core::ops::Range { start: 7, end: 12 },
|
||||
curve_id_index: 0,
|
||||
private_key_index: 0x10,
|
||||
};
|
||||
84
zeroidc/vendor/ring/src/ec/curve25519/ed25519/verification.rs
vendored
Normal file
84
zeroidc/vendor/ring/src/ec/curve25519/ed25519/verification.rs
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! EdDSA Signatures.
|
||||
|
||||
use super::{super::ops::*, eddsa_digest};
|
||||
use crate::{error, sealed, signature};
|
||||
use core::convert::TryInto;
|
||||
|
||||
/// Parameters for EdDSA signing and verification.
|
||||
pub struct EdDSAParameters;
|
||||
|
||||
impl core::fmt::Debug for EdDSAParameters {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
write!(f, "ring::signature::ED25519")
|
||||
}
|
||||
}
|
||||
|
||||
/// Verification of [Ed25519] signatures.
|
||||
///
|
||||
/// Ed25519 uses SHA-512 as the digest algorithm.
|
||||
///
|
||||
/// [Ed25519]: https://ed25519.cr.yp.to/
|
||||
pub static ED25519: EdDSAParameters = EdDSAParameters {};
|
||||
|
||||
impl signature::VerificationAlgorithm for EdDSAParameters {
|
||||
fn verify(
|
||||
&self,
|
||||
public_key: untrusted::Input,
|
||||
msg: untrusted::Input,
|
||||
signature: untrusted::Input,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
let public_key: &[u8; ELEM_LEN] = public_key.as_slice_less_safe().try_into()?;
|
||||
let (signature_r, signature_s) = signature.read_all(error::Unspecified, |input| {
|
||||
let signature_r: &[u8; ELEM_LEN] = input
|
||||
.read_bytes(ELEM_LEN)?
|
||||
.as_slice_less_safe()
|
||||
.try_into()?;
|
||||
let signature_s: &[u8; SCALAR_LEN] = input
|
||||
.read_bytes(SCALAR_LEN)?
|
||||
.as_slice_less_safe()
|
||||
.try_into()?;
|
||||
Ok((signature_r, signature_s))
|
||||
})?;
|
||||
|
||||
let signature_s = Scalar::from_bytes_checked(*signature_s)?;
|
||||
|
||||
let mut a = ExtPoint::from_encoded_point_vartime(public_key)?;
|
||||
a.invert_vartime();
|
||||
|
||||
let h_digest = eddsa_digest(signature_r, public_key, msg.as_slice_less_safe());
|
||||
let h = Scalar::from_sha512_digest_reduced(h_digest);
|
||||
|
||||
let mut r = Point::new_at_infinity();
|
||||
unsafe { GFp_x25519_ge_double_scalarmult_vartime(&mut r, &h, &a, &signature_s) };
|
||||
let r_check = r.into_encoded_point();
|
||||
if *signature_r != r_check {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl sealed::Sealed for EdDSAParameters {}
|
||||
|
||||
extern "C" {
|
||||
fn GFp_x25519_ge_double_scalarmult_vartime(
|
||||
r: &mut Point,
|
||||
a_coeff: &Scalar,
|
||||
a: &ExtPoint,
|
||||
b_coeff: &Scalar,
|
||||
);
|
||||
}
|
||||
155
zeroidc/vendor/ring/src/ec/curve25519/ops.rs
vendored
Normal file
155
zeroidc/vendor/ring/src/ec/curve25519/ops.rs
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
// Copyright 2015-2017 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Elliptic curve operations on the birationally equivalent curves Curve25519
|
||||
//! and Edwards25519.
|
||||
|
||||
pub use super::scalar::{MaskedScalar, Scalar, SCALAR_LEN};
|
||||
use crate::{
|
||||
bssl, error,
|
||||
limb::{Limb, LIMB_BITS},
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
// Elem<T>` is `fe` in curve25519/internal.h.
|
||||
// Elem<L> is `fe_loose` in curve25519/internal.h.
|
||||
// Keep this in sync with curve25519/internal.h.
|
||||
#[repr(C)]
|
||||
pub struct Elem<E: Encoding> {
|
||||
limbs: [Limb; ELEM_LIMBS], // This is called `v` in the C code.
|
||||
encoding: PhantomData<E>,
|
||||
}
|
||||
|
||||
pub trait Encoding {}
|
||||
pub struct T;
|
||||
impl Encoding for T {}
|
||||
|
||||
const ELEM_LIMBS: usize = 5 * 64 / LIMB_BITS;
|
||||
|
||||
impl<E: Encoding> Elem<E> {
|
||||
fn zero() -> Self {
|
||||
Self {
|
||||
limbs: Default::default(),
|
||||
encoding: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Elem<T> {
|
||||
fn negate(&mut self) {
|
||||
unsafe {
|
||||
GFp_x25519_fe_neg(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// An encoding of a curve point. If on Curve25519, it should be encoded as
|
||||
// described in Section 5 of [RFC 7748]. If on Edwards25519, it should be
|
||||
// encoded as described in section 5.1.2 of [RFC 8032].
|
||||
//
|
||||
// [RFC 7748] https://tools.ietf.org/html/rfc7748#section-5
|
||||
// [RFC 8032] https://tools.ietf.org/html/rfc8032#section-5.1.2
|
||||
pub type EncodedPoint = [u8; ELEM_LEN];
|
||||
pub const ELEM_LEN: usize = 32;
|
||||
|
||||
// Keep this in sync with `ge_p3` in curve25519/internal.h.
|
||||
#[repr(C)]
|
||||
pub struct ExtPoint {
|
||||
x: Elem<T>,
|
||||
y: Elem<T>,
|
||||
z: Elem<T>,
|
||||
t: Elem<T>,
|
||||
}
|
||||
|
||||
impl ExtPoint {
|
||||
pub fn new_at_infinity() -> Self {
|
||||
Self {
|
||||
x: Elem::zero(),
|
||||
y: Elem::zero(),
|
||||
z: Elem::zero(),
|
||||
t: Elem::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_encoded_point_vartime(encoded: &EncodedPoint) -> Result<Self, error::Unspecified> {
|
||||
let mut point = Self::new_at_infinity();
|
||||
|
||||
Result::from(unsafe { GFp_x25519_ge_frombytes_vartime(&mut point, encoded) })
|
||||
.map(|()| point)
|
||||
}
|
||||
|
||||
pub fn into_encoded_point(self) -> EncodedPoint {
|
||||
encode_point(self.x, self.y, self.z)
|
||||
}
|
||||
|
||||
pub fn invert_vartime(&mut self) {
|
||||
self.x.negate();
|
||||
self.t.negate();
|
||||
}
|
||||
}
|
||||
|
||||
// Keep this in sync with `ge_p2` in curve25519/internal.h.
|
||||
#[repr(C)]
|
||||
pub struct Point {
|
||||
x: Elem<T>,
|
||||
y: Elem<T>,
|
||||
z: Elem<T>,
|
||||
}
|
||||
|
||||
impl Point {
|
||||
pub fn new_at_infinity() -> Self {
|
||||
Self {
|
||||
x: Elem::zero(),
|
||||
y: Elem::zero(),
|
||||
z: Elem::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_encoded_point(self) -> EncodedPoint {
|
||||
encode_point(self.x, self.y, self.z)
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_point(x: Elem<T>, y: Elem<T>, z: Elem<T>) -> EncodedPoint {
|
||||
let mut bytes = [0; ELEM_LEN];
|
||||
|
||||
let sign_bit: u8 = unsafe {
|
||||
let mut recip = Elem::zero();
|
||||
GFp_x25519_fe_invert(&mut recip, &z);
|
||||
|
||||
let mut x_over_z = Elem::zero();
|
||||
GFp_x25519_fe_mul_ttt(&mut x_over_z, &x, &recip);
|
||||
|
||||
let mut y_over_z = Elem::zero();
|
||||
GFp_x25519_fe_mul_ttt(&mut y_over_z, &y, &recip);
|
||||
GFp_x25519_fe_tobytes(&mut bytes, &y_over_z);
|
||||
|
||||
GFp_x25519_fe_isnegative(&x_over_z)
|
||||
};
|
||||
|
||||
// The preceding computations must execute in constant time, but this
|
||||
// doesn't need to.
|
||||
bytes[ELEM_LEN - 1] ^= sign_bit << 7;
|
||||
|
||||
bytes
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn GFp_x25519_fe_invert(out: &mut Elem<T>, z: &Elem<T>);
|
||||
fn GFp_x25519_fe_isnegative(elem: &Elem<T>) -> u8;
|
||||
fn GFp_x25519_fe_mul_ttt(h: &mut Elem<T>, f: &Elem<T>, g: &Elem<T>);
|
||||
fn GFp_x25519_fe_neg(f: &mut Elem<T>);
|
||||
fn GFp_x25519_fe_tobytes(bytes: &mut EncodedPoint, elem: &Elem<T>);
|
||||
fn GFp_x25519_ge_frombytes_vartime(h: &mut ExtPoint, s: &EncodedPoint) -> bssl::Result;
|
||||
}
|
||||
78
zeroidc/vendor/ring/src/ec/curve25519/scalar.rs
vendored
Normal file
78
zeroidc/vendor/ring/src/ec/curve25519/scalar.rs
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2015-2019 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use crate::{digest, error, limb};
|
||||
use core::convert::TryInto;
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Scalar([u8; SCALAR_LEN]);
|
||||
|
||||
pub const SCALAR_LEN: usize = 32;
|
||||
|
||||
impl Scalar {
|
||||
// Constructs a `Scalar` from `bytes`, failing if `bytes` encodes a scalar
|
||||
// that not in the range [0, n).
|
||||
pub fn from_bytes_checked(bytes: [u8; SCALAR_LEN]) -> Result<Self, error::Unspecified> {
|
||||
const ORDER: [limb::Limb; SCALAR_LEN / limb::LIMB_BYTES] =
|
||||
limbs![0x5cf5d3ed, 0x5812631a, 0xa2f79cd6, 0x14def9de, 0, 0, 0, 0x10000000];
|
||||
|
||||
// `bytes` is in little-endian order.
|
||||
let mut reversed = bytes;
|
||||
reversed.reverse();
|
||||
|
||||
let mut limbs = [0; SCALAR_LEN / limb::LIMB_BYTES];
|
||||
limb::parse_big_endian_in_range_and_pad_consttime(
|
||||
untrusted::Input::from(&reversed),
|
||||
limb::AllowZero::Yes,
|
||||
&ORDER,
|
||||
&mut limbs,
|
||||
)?;
|
||||
|
||||
Ok(Self(bytes))
|
||||
}
|
||||
|
||||
// Constructs a `Scalar` from `digest` reduced modulo n.
|
||||
pub fn from_sha512_digest_reduced(digest: digest::Digest) -> Self {
|
||||
extern "C" {
|
||||
fn GFp_x25519_sc_reduce(s: &mut UnreducedScalar);
|
||||
}
|
||||
let mut unreduced = [0u8; digest::SHA512_OUTPUT_LEN];
|
||||
unreduced.copy_from_slice(digest.as_ref());
|
||||
unsafe { GFp_x25519_sc_reduce(&mut unreduced) };
|
||||
Self((&unreduced[..SCALAR_LEN]).try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct MaskedScalar([u8; SCALAR_LEN]);
|
||||
|
||||
impl MaskedScalar {
|
||||
pub fn from_bytes_masked(bytes: [u8; SCALAR_LEN]) -> Self {
|
||||
extern "C" {
|
||||
fn GFp_x25519_sc_mask(a: &mut [u8; SCALAR_LEN]);
|
||||
}
|
||||
let mut r = Self(bytes);
|
||||
unsafe { GFp_x25519_sc_mask(&mut r.0) };
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MaskedScalar> for Scalar {
|
||||
fn from(MaskedScalar(scalar): MaskedScalar) -> Self {
|
||||
Self(scalar)
|
||||
}
|
||||
}
|
||||
|
||||
type UnreducedScalar = [u8; UNREDUCED_SCALAR_LEN];
|
||||
const UNREDUCED_SCALAR_LEN: usize = SCALAR_LEN * 2;
|
||||
170
zeroidc/vendor/ring/src/ec/curve25519/x25519.rs
vendored
Normal file
170
zeroidc/vendor/ring/src/ec/curve25519/x25519.rs
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! X25519 Key agreement.
|
||||
|
||||
use super::{ops, scalar::SCALAR_LEN};
|
||||
use crate::{agreement, constant_time, cpu, ec, error, rand};
|
||||
use core::convert::TryInto;
|
||||
|
||||
static CURVE25519: ec::Curve = ec::Curve {
|
||||
public_key_len: PUBLIC_KEY_LEN,
|
||||
elem_scalar_seed_len: ELEM_AND_SCALAR_LEN,
|
||||
id: ec::CurveID::Curve25519,
|
||||
check_private_key_bytes: x25519_check_private_key_bytes,
|
||||
generate_private_key: x25519_generate_private_key,
|
||||
public_from_private: x25519_public_from_private,
|
||||
};
|
||||
|
||||
/// X25519 (ECDH using Curve25519) as described in [RFC 7748].
|
||||
///
|
||||
/// Everything is as described in RFC 7748. Key agreement will fail if the
|
||||
/// result of the X25519 operation is zero; see the notes on the
|
||||
/// "all-zero value" in [RFC 7748 section 6.1].
|
||||
///
|
||||
/// [RFC 7748]: https://tools.ietf.org/html/rfc7748
|
||||
/// [RFC 7748 section 6.1]: https://tools.ietf.org/html/rfc7748#section-6.1
|
||||
pub static X25519: agreement::Algorithm = agreement::Algorithm {
|
||||
curve: &CURVE25519,
|
||||
ecdh: x25519_ecdh,
|
||||
};
|
||||
|
||||
fn x25519_check_private_key_bytes(bytes: &[u8]) -> Result<(), error::Unspecified> {
|
||||
debug_assert_eq!(bytes.len(), PRIVATE_KEY_LEN);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn x25519_generate_private_key(
|
||||
rng: &dyn rand::SecureRandom,
|
||||
out: &mut [u8],
|
||||
) -> Result<(), error::Unspecified> {
|
||||
rng.fill(out)
|
||||
}
|
||||
|
||||
fn x25519_public_from_private(
|
||||
public_out: &mut [u8],
|
||||
private_key: &ec::Seed,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
let public_out = public_out.try_into()?;
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
let cpu_features = private_key.cpu_features;
|
||||
|
||||
let private_key: &[u8; SCALAR_LEN] = private_key.bytes_less_safe().try_into()?;
|
||||
let private_key = ops::MaskedScalar::from_bytes_masked(*private_key);
|
||||
|
||||
#[cfg(all(not(target_os = "ios"), target_arch = "arm"))]
|
||||
{
|
||||
if cpu::arm::NEON.available(cpu_features) {
|
||||
static MONTGOMERY_BASE_POINT: [u8; 32] = [
|
||||
9, 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,
|
||||
];
|
||||
x25519_neon(public_out, &private_key, &MONTGOMERY_BASE_POINT);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn GFp_x25519_public_from_private_generic_masked(
|
||||
public_key_out: &mut PublicKey,
|
||||
private_key: &PrivateKey,
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
GFp_x25519_public_from_private_generic_masked(public_out, &private_key);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn x25519_ecdh(
|
||||
out: &mut [u8],
|
||||
my_private_key: &ec::Seed,
|
||||
peer_public_key: untrusted::Input,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
let cpu_features = my_private_key.cpu_features;
|
||||
let my_private_key: &[u8; SCALAR_LEN] = my_private_key.bytes_less_safe().try_into()?;
|
||||
let my_private_key = ops::MaskedScalar::from_bytes_masked(*my_private_key);
|
||||
let peer_public_key: &[u8; PUBLIC_KEY_LEN] = peer_public_key.as_slice_less_safe().try_into()?;
|
||||
|
||||
#[cfg_attr(
|
||||
not(all(not(target_os = "ios"), target_arch = "arm")),
|
||||
allow(unused_variables)
|
||||
)]
|
||||
fn scalar_mult(
|
||||
out: &mut ops::EncodedPoint,
|
||||
scalar: &ops::MaskedScalar,
|
||||
point: &ops::EncodedPoint,
|
||||
cpu_features: cpu::Features,
|
||||
) {
|
||||
#[cfg(all(not(target_os = "ios"), target_arch = "arm"))]
|
||||
{
|
||||
if cpu::arm::NEON.available(cpu_features) {
|
||||
return x25519_neon(out, scalar, point);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn GFp_x25519_scalar_mult_generic_masked(
|
||||
out: &mut ops::EncodedPoint,
|
||||
scalar: &ops::MaskedScalar,
|
||||
point: &ops::EncodedPoint,
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
GFp_x25519_scalar_mult_generic_masked(out, scalar, point);
|
||||
}
|
||||
}
|
||||
|
||||
scalar_mult(
|
||||
out.try_into()?,
|
||||
&my_private_key,
|
||||
peer_public_key,
|
||||
cpu_features,
|
||||
);
|
||||
|
||||
let zeros: SharedSecret = [0; SHARED_SECRET_LEN];
|
||||
if constant_time::verify_slices_are_equal(out, &zeros).is_ok() {
|
||||
// All-zero output results when the input is a point of small order.
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(all(not(target_os = "ios"), target_arch = "arm"))]
|
||||
fn x25519_neon(out: &mut ops::EncodedPoint, scalar: &ops::MaskedScalar, point: &ops::EncodedPoint) {
|
||||
extern "C" {
|
||||
fn GFp_x25519_NEON(
|
||||
out: &mut ops::EncodedPoint,
|
||||
scalar: &ops::MaskedScalar,
|
||||
point: &ops::EncodedPoint,
|
||||
);
|
||||
}
|
||||
unsafe { GFp_x25519_NEON(out, scalar, point) }
|
||||
}
|
||||
|
||||
const ELEM_AND_SCALAR_LEN: usize = ops::ELEM_LEN;
|
||||
|
||||
type PrivateKey = ops::MaskedScalar;
|
||||
const PRIVATE_KEY_LEN: usize = ELEM_AND_SCALAR_LEN;
|
||||
|
||||
// An X25519 public key as an encoded Curve25519 point.
|
||||
type PublicKey = [u8; PUBLIC_KEY_LEN];
|
||||
const PUBLIC_KEY_LEN: usize = ELEM_AND_SCALAR_LEN;
|
||||
|
||||
// An X25519 shared secret as an encoded Curve25519 point.
|
||||
type SharedSecret = [u8; SHARED_SECRET_LEN];
|
||||
const SHARED_SECRET_LEN: usize = ELEM_AND_SCALAR_LEN;
|
||||
90
zeroidc/vendor/ring/src/ec/keys.rs
vendored
Normal file
90
zeroidc/vendor/ring/src/ec/keys.rs
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
use super::{Curve, ELEM_MAX_BYTES, SEED_MAX_BYTES};
|
||||
use crate::{cpu, error, rand};
|
||||
|
||||
pub struct KeyPair {
|
||||
seed: Seed,
|
||||
public_key: PublicKey,
|
||||
}
|
||||
|
||||
impl KeyPair {
|
||||
pub fn derive(seed: Seed) -> Result<Self, error::Unspecified> {
|
||||
let public_key = seed.compute_public_key()?;
|
||||
Ok(Self { seed, public_key })
|
||||
}
|
||||
|
||||
pub fn public_key(&self) -> &PublicKey {
|
||||
&self.public_key
|
||||
}
|
||||
pub fn split(self) -> (Seed, PublicKey) {
|
||||
(self.seed, self.public_key)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Seed {
|
||||
bytes: [u8; SEED_MAX_BYTES],
|
||||
curve: &'static Curve,
|
||||
pub(crate) cpu_features: cpu::Features,
|
||||
}
|
||||
|
||||
impl Seed {
|
||||
pub(crate) fn generate(
|
||||
curve: &'static Curve,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Result<Self, error::Unspecified> {
|
||||
let mut r = Self {
|
||||
bytes: [0u8; SEED_MAX_BYTES],
|
||||
curve,
|
||||
cpu_features,
|
||||
};
|
||||
(curve.generate_private_key)(rng, &mut r.bytes[..curve.elem_scalar_seed_len])?;
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
pub(crate) fn from_bytes(
|
||||
curve: &'static Curve,
|
||||
bytes: untrusted::Input,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Result<Seed, error::Unspecified> {
|
||||
let bytes = bytes.as_slice_less_safe();
|
||||
if curve.elem_scalar_seed_len != bytes.len() {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
(curve.check_private_key_bytes)(bytes)?;
|
||||
let mut r = Self {
|
||||
bytes: [0; SEED_MAX_BYTES],
|
||||
curve,
|
||||
cpu_features,
|
||||
};
|
||||
r.bytes[..curve.elem_scalar_seed_len].copy_from_slice(bytes);
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
pub fn bytes_less_safe(&self) -> &[u8] {
|
||||
&self.bytes[..self.curve.elem_scalar_seed_len]
|
||||
}
|
||||
|
||||
pub fn compute_public_key(&self) -> Result<PublicKey, error::Unspecified> {
|
||||
let mut public_key = PublicKey {
|
||||
bytes: [0u8; PUBLIC_KEY_MAX_LEN],
|
||||
len: self.curve.public_key_len,
|
||||
};
|
||||
(self.curve.public_from_private)(&mut public_key.bytes[..public_key.len], self)?;
|
||||
Ok(public_key)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct PublicKey {
|
||||
bytes: [u8; PUBLIC_KEY_MAX_LEN],
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for PublicKey {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.bytes[..self.len]
|
||||
}
|
||||
}
|
||||
|
||||
/// The maximum length, in bytes, of an encoded public key.
|
||||
pub const PUBLIC_KEY_MAX_LEN: usize = 1 + (2 * ELEM_MAX_BYTES);
|
||||
237
zeroidc/vendor/ring/src/ec/suite_b.rs
vendored
Normal file
237
zeroidc/vendor/ring/src/ec/suite_b.rs
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Elliptic curve operations on P-256 & P-384.
|
||||
|
||||
use self::ops::*;
|
||||
use crate::{arithmetic::montgomery::*, cpu, ec, error, io::der, limb::LimbMask, pkcs8};
|
||||
|
||||
// NIST SP 800-56A Step 3: "If q is an odd prime p, verify that
|
||||
// yQ**2 = xQ**3 + axQ + b in GF(p), where the arithmetic is performed modulo
|
||||
// p."
|
||||
//
|
||||
// That is, verify that (x, y) is on the curve, which is true iif:
|
||||
//
|
||||
// y**2 == x**3 + a*x + b (mod q)
|
||||
//
|
||||
// Or, equivalently, but more efficiently:
|
||||
//
|
||||
// y**2 == (x**2 + a)*x + b (mod q)
|
||||
//
|
||||
fn verify_affine_point_is_on_the_curve(
|
||||
ops: &CommonOps,
|
||||
(x, y): (&Elem<R>, &Elem<R>),
|
||||
) -> Result<(), error::Unspecified> {
|
||||
verify_affine_point_is_on_the_curve_scaled(ops, (x, y), &ops.a, &ops.b)
|
||||
}
|
||||
|
||||
// Use `verify_affine_point_is_on_the_curve` instead of this function whenever
|
||||
// the affine coordinates are available or will become available. This function
|
||||
// should only be used then the affine coordinates are never calculated. See
|
||||
// the notes for `verify_affine_point_is_on_the_curve_scaled`.
|
||||
//
|
||||
// The value `z**2` is returned on success because it is useful for ECDSA
|
||||
// verification.
|
||||
//
|
||||
// This function also verifies that the point is not at infinity.
|
||||
fn verify_jacobian_point_is_on_the_curve(
|
||||
ops: &CommonOps,
|
||||
p: &Point,
|
||||
) -> Result<Elem<R>, error::Unspecified> {
|
||||
let z = ops.point_z(p);
|
||||
|
||||
// Verify that the point is not at infinity.
|
||||
ops.elem_verify_is_not_zero(&z)?;
|
||||
|
||||
let x = ops.point_x(p);
|
||||
let y = ops.point_y(p);
|
||||
|
||||
// We are given Jacobian coordinates (x, y, z). So, we have:
|
||||
//
|
||||
// (x/z**2, y/z**3) == (x', y'),
|
||||
//
|
||||
// where (x', y') are the affine coordinates. The curve equation is:
|
||||
//
|
||||
// y'**2 == x'**3 + a*x' + b == (x'**2 + a)*x' + b
|
||||
//
|
||||
// Substituting our Jacobian coordinates, we get:
|
||||
//
|
||||
// / y \**2 / / x \**2 \ / x \
|
||||
// | ---- | == | | ---- | + a | * | ---- | + b
|
||||
// \ z**3 / \ \ z**2 / / \ z**2 /
|
||||
//
|
||||
// Simplify:
|
||||
//
|
||||
// y**2 / x**2 \ x
|
||||
// ---- == | ---- + a | * ---- + b
|
||||
// z**6 \ z**4 / z**2
|
||||
//
|
||||
// Multiply both sides by z**6:
|
||||
//
|
||||
// z**6 / x**2 \ z**6
|
||||
// ---- * y**2 == | ---- + a | * ---- * x + (z**6) * b
|
||||
// z**6 \ z**4 / z**2
|
||||
//
|
||||
// Simplify:
|
||||
//
|
||||
// / x**2 \
|
||||
// y**2 == | ---- + a | * z**4 * x + (z**6) * b
|
||||
// \ z**4 /
|
||||
//
|
||||
// Distribute z**4:
|
||||
//
|
||||
// / z**4 \
|
||||
// y**2 == | ---- * x**2 + z**4 * a | * x + (z**6) * b
|
||||
// \ z**4 /
|
||||
//
|
||||
// Simplify:
|
||||
//
|
||||
// y**2 == (x**2 + z**4 * a) * x + (z**6) * b
|
||||
//
|
||||
let z2 = ops.elem_squared(&z);
|
||||
let z4 = ops.elem_squared(&z2);
|
||||
let z4_a = ops.elem_product(&z4, &ops.a);
|
||||
let z6 = ops.elem_product(&z4, &z2);
|
||||
let z6_b = ops.elem_product(&z6, &ops.b);
|
||||
verify_affine_point_is_on_the_curve_scaled(ops, (&x, &y), &z4_a, &z6_b)?;
|
||||
Ok(z2)
|
||||
}
|
||||
|
||||
// Handles the common logic of point-is-on-the-curve checks for both affine and
|
||||
// Jacobian cases.
|
||||
//
|
||||
// When doing the check that the point is on the curve after a computation,
|
||||
// to avoid fault attacks or mitigate potential bugs, it is better for security
|
||||
// to use `verify_affine_point_is_on_the_curve` on the affine coordinates,
|
||||
// because it provides some protection against faults that occur in the
|
||||
// computation of the inverse of `z`. See the paper and presentation "Fault
|
||||
// Attacks on Projective-to-Affine Coordinates Conversion" by Diana Maimuţ,
|
||||
// Cédric Murdica, David Naccache, Mehdi Tibouchi. That presentation concluded
|
||||
// simply "Check the validity of the result after conversion to affine
|
||||
// coordinates." (It seems like a good idea to verify that
|
||||
// z_inv * z == 1 mod q too).
|
||||
//
|
||||
// In the case of affine coordinates (x, y), `a_scaled` and `b_scaled` are
|
||||
// `a` and `b`, respectively. In the case of Jacobian coordinates (x, y, z),
|
||||
// the computation and comparison is the same, except `a_scaled` and `b_scaled`
|
||||
// are (z**4 * a) and (z**6 * b), respectively. Thus, performance is another
|
||||
// reason to prefer doing the check on the affine coordinates, as Jacobian
|
||||
// computation requires 3 extra multiplications and 2 extra squarings.
|
||||
//
|
||||
// An example of a fault attack that isn't mitigated by a point-on-the-curve
|
||||
// check after multiplication is given in "Sign Change Fault Attacks On
|
||||
// Elliptic Curve Cryptosystems" by Johannes Blömer, Martin Otto, and
|
||||
// Jean-Pierre Seifert.
|
||||
fn verify_affine_point_is_on_the_curve_scaled(
|
||||
ops: &CommonOps,
|
||||
(x, y): (&Elem<R>, &Elem<R>),
|
||||
a_scaled: &Elem<R>,
|
||||
b_scaled: &Elem<R>,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
let lhs = ops.elem_squared(y);
|
||||
|
||||
let mut rhs = ops.elem_squared(x);
|
||||
ops.elem_add(&mut rhs, a_scaled);
|
||||
ops.elem_mul(&mut rhs, x);
|
||||
ops.elem_add(&mut rhs, b_scaled);
|
||||
|
||||
if ops.elems_are_equal(&lhs, &rhs) != LimbMask::True {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn key_pair_from_pkcs8(
|
||||
curve: &'static ec::Curve,
|
||||
template: &pkcs8::Template,
|
||||
input: untrusted::Input,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Result<ec::KeyPair, error::KeyRejected> {
|
||||
let (ec_private_key, _) = pkcs8::unwrap_key(template, pkcs8::Version::V1Only, input)?;
|
||||
let (private_key, public_key) =
|
||||
ec_private_key.read_all(error::KeyRejected::invalid_encoding(), |input| {
|
||||
// https://tools.ietf.org/html/rfc5915#section-3
|
||||
der::nested(
|
||||
input,
|
||||
der::Tag::Sequence,
|
||||
error::KeyRejected::invalid_encoding(),
|
||||
|input| key_pair_from_pkcs8_(template, input),
|
||||
)
|
||||
})?;
|
||||
key_pair_from_bytes(curve, private_key, public_key, cpu_features)
|
||||
}
|
||||
|
||||
fn key_pair_from_pkcs8_<'a>(
|
||||
template: &pkcs8::Template,
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
) -> Result<(untrusted::Input<'a>, untrusted::Input<'a>), error::KeyRejected> {
|
||||
let version = der::small_nonnegative_integer(input)
|
||||
.map_err(|error::Unspecified| error::KeyRejected::invalid_encoding())?;
|
||||
if version != 1 {
|
||||
return Err(error::KeyRejected::version_not_supported());
|
||||
}
|
||||
|
||||
let private_key = der::expect_tag_and_get_value(input, der::Tag::OctetString)
|
||||
.map_err(|error::Unspecified| error::KeyRejected::invalid_encoding())?;
|
||||
|
||||
// [0] parameters (optional).
|
||||
if input.peek(u8::from(der::Tag::ContextSpecificConstructed0)) {
|
||||
let actual_alg_id =
|
||||
der::expect_tag_and_get_value(input, der::Tag::ContextSpecificConstructed0)
|
||||
.map_err(|error::Unspecified| error::KeyRejected::invalid_encoding())?;
|
||||
if actual_alg_id != template.curve_oid() {
|
||||
return Err(error::KeyRejected::wrong_algorithm());
|
||||
}
|
||||
}
|
||||
|
||||
// [1] publicKey. The RFC says it is optional, but we require it
|
||||
// to be present.
|
||||
let public_key = der::nested(
|
||||
input,
|
||||
der::Tag::ContextSpecificConstructed1,
|
||||
error::Unspecified,
|
||||
der::bit_string_with_no_unused_bits,
|
||||
)
|
||||
.map_err(|error::Unspecified| error::KeyRejected::invalid_encoding())?;
|
||||
|
||||
Ok((private_key, public_key))
|
||||
}
|
||||
|
||||
pub(crate) fn key_pair_from_bytes(
|
||||
curve: &'static ec::Curve,
|
||||
private_key_bytes: untrusted::Input,
|
||||
public_key_bytes: untrusted::Input,
|
||||
cpu_features: cpu::Features,
|
||||
) -> Result<ec::KeyPair, error::KeyRejected> {
|
||||
let seed = ec::Seed::from_bytes(curve, private_key_bytes, cpu_features)
|
||||
.map_err(|error::Unspecified| error::KeyRejected::invalid_component())?;
|
||||
|
||||
let r = ec::KeyPair::derive(seed)
|
||||
.map_err(|error::Unspecified| error::KeyRejected::unexpected_error())?;
|
||||
if public_key_bytes != *r.public_key().as_ref() {
|
||||
return Err(error::KeyRejected::inconsistent_components());
|
||||
}
|
||||
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
pub mod curve;
|
||||
pub mod ecdh;
|
||||
pub mod ecdsa;
|
||||
|
||||
mod ops;
|
||||
|
||||
mod private_key;
|
||||
mod public_key;
|
||||
83
zeroidc/vendor/ring/src/ec/suite_b/curve.rs
vendored
Normal file
83
zeroidc/vendor/ring/src/ec/suite_b/curve.rs
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright 2015-2017 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use crate::{ec, error, rand};
|
||||
|
||||
/// A key agreement algorithm.
|
||||
macro_rules! suite_b_curve {
|
||||
( $NAME:ident, $bits:expr, $private_key_ops:expr, $id:expr,
|
||||
$check_private_key_bytes:ident, $generate_private_key:ident,
|
||||
$public_from_private:ident) => {
|
||||
/// Public keys are encoding in uncompressed form using the
|
||||
/// Octet-String-to-Elliptic-Curve-Point algorithm in
|
||||
/// [SEC 1: Elliptic Curve Cryptography, Version 2.0]. Public keys are
|
||||
/// validated during key agreement according to
|
||||
/// [NIST Special Publication 800-56A, revision 2] and Appendix B.3 of
|
||||
/// the NSA's [Suite B Implementer's Guide to NIST SP 800-56A].
|
||||
///
|
||||
/// [SEC 1: Elliptic Curve Cryptography, Version 2.0]:
|
||||
/// http://www.secg.org/sec1-v2.pdf
|
||||
/// [NIST Special Publication 800-56A, revision 2]:
|
||||
/// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf
|
||||
/// [Suite B Implementer's Guide to NIST SP 800-56A]:
|
||||
/// https://github.com/briansmith/ring/blob/main/doc/ecdh.pdf
|
||||
pub static $NAME: ec::Curve = ec::Curve {
|
||||
public_key_len: 1 + (2 * (($bits + 7) / 8)),
|
||||
elem_scalar_seed_len: ($bits + 7) / 8,
|
||||
id: $id,
|
||||
check_private_key_bytes: $check_private_key_bytes,
|
||||
generate_private_key: $generate_private_key,
|
||||
public_from_private: $public_from_private,
|
||||
};
|
||||
|
||||
fn $check_private_key_bytes(bytes: &[u8]) -> Result<(), error::Unspecified> {
|
||||
debug_assert_eq!(bytes.len(), $bits / 8);
|
||||
ec::suite_b::private_key::check_scalar_big_endian_bytes($private_key_ops, bytes)
|
||||
}
|
||||
|
||||
fn $generate_private_key(
|
||||
rng: &dyn rand::SecureRandom,
|
||||
out: &mut [u8],
|
||||
) -> Result<(), error::Unspecified> {
|
||||
ec::suite_b::private_key::generate_private_scalar_bytes($private_key_ops, rng, out)
|
||||
}
|
||||
|
||||
fn $public_from_private(
|
||||
public_out: &mut [u8],
|
||||
private_key: &ec::Seed,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
ec::suite_b::private_key::public_from_private($private_key_ops, public_out, private_key)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
suite_b_curve!(
|
||||
P256,
|
||||
256,
|
||||
&ec::suite_b::ops::p256::PRIVATE_KEY_OPS,
|
||||
ec::CurveID::P256,
|
||||
p256_check_private_key_bytes,
|
||||
p256_generate_private_key,
|
||||
p256_public_from_private
|
||||
);
|
||||
|
||||
suite_b_curve!(
|
||||
P384,
|
||||
384,
|
||||
&ec::suite_b::ops::p384::PRIVATE_KEY_OPS,
|
||||
ec::CurveID::P384,
|
||||
p384_check_private_key_bytes,
|
||||
p384_generate_private_key,
|
||||
p384_public_from_private
|
||||
);
|
||||
236
zeroidc/vendor/ring/src/ec/suite_b/ecdh.rs
vendored
Normal file
236
zeroidc/vendor/ring/src/ec/suite_b/ecdh.rs
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
// Copyright 2015-2017 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! ECDH key agreement using the P-256 and P-384 curves.
|
||||
|
||||
use super::{ops::*, private_key::*, public_key::*};
|
||||
use crate::{agreement, ec, error};
|
||||
|
||||
/// A key agreement algorithm.
|
||||
macro_rules! ecdh {
|
||||
( $NAME:ident, $curve:expr, $name_str:expr, $private_key_ops:expr,
|
||||
$public_key_ops:expr, $ecdh:ident ) => {
|
||||
#[doc = "ECDH using the NSA Suite B"]
|
||||
#[doc=$name_str]
|
||||
#[doc = "curve."]
|
||||
///
|
||||
/// Public keys are encoding in uncompressed form using the
|
||||
/// Octet-String-to-Elliptic-Curve-Point algorithm in
|
||||
/// [SEC 1: Elliptic Curve Cryptography, Version 2.0]. Public keys are
|
||||
/// validated during key agreement according to
|
||||
/// [NIST Special Publication 800-56A, revision 2] and Appendix B.3 of
|
||||
/// the NSA's [Suite B Implementer's Guide to NIST SP 800-56A].
|
||||
///
|
||||
/// [SEC 1: Elliptic Curve Cryptography, Version 2.0]:
|
||||
/// http://www.secg.org/sec1-v2.pdf
|
||||
/// [NIST Special Publication 800-56A, revision 2]:
|
||||
/// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf
|
||||
/// [Suite B Implementer's Guide to NIST SP 800-56A]:
|
||||
/// https://github.com/briansmith/ring/blob/main/doc/ecdh.pdf
|
||||
pub static $NAME: agreement::Algorithm = agreement::Algorithm {
|
||||
curve: $curve,
|
||||
ecdh: $ecdh,
|
||||
};
|
||||
|
||||
fn $ecdh(
|
||||
out: &mut [u8],
|
||||
my_private_key: &ec::Seed,
|
||||
peer_public_key: untrusted::Input,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
ecdh(
|
||||
$private_key_ops,
|
||||
$public_key_ops,
|
||||
out,
|
||||
my_private_key,
|
||||
peer_public_key,
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ecdh!(
|
||||
ECDH_P256,
|
||||
&ec::suite_b::curve::P256,
|
||||
"P-256 (secp256r1)",
|
||||
&p256::PRIVATE_KEY_OPS,
|
||||
&p256::PUBLIC_KEY_OPS,
|
||||
p256_ecdh
|
||||
);
|
||||
|
||||
ecdh!(
|
||||
ECDH_P384,
|
||||
&ec::suite_b::curve::P384,
|
||||
"P-384 (secp384r1)",
|
||||
&p384::PRIVATE_KEY_OPS,
|
||||
&p384::PUBLIC_KEY_OPS,
|
||||
p384_ecdh
|
||||
);
|
||||
|
||||
fn ecdh(
|
||||
private_key_ops: &PrivateKeyOps,
|
||||
public_key_ops: &PublicKeyOps,
|
||||
out: &mut [u8],
|
||||
my_private_key: &ec::Seed,
|
||||
peer_public_key: untrusted::Input,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
// The NIST SP 800-56Ar2 steps are from section 5.7.1.2 Elliptic Curve
|
||||
// Cryptography Cofactor Diffie-Hellman (ECC CDH) Primitive.
|
||||
//
|
||||
// The "NSA Guide" steps are from section 3.1 of the NSA guide, "Ephemeral
|
||||
// Unified Model."
|
||||
|
||||
// NSA Guide Step 1 is handled separately.
|
||||
|
||||
// NIST SP 800-56Ar2 5.6.2.2.2.
|
||||
// NSA Guide Step 2.
|
||||
//
|
||||
// `parse_uncompressed_point` verifies that the point is not at infinity
|
||||
// and that it is on the curve, using the Partial Public-Key Validation
|
||||
// Routine.
|
||||
let peer_public_key = parse_uncompressed_point(public_key_ops, peer_public_key)?;
|
||||
|
||||
// NIST SP 800-56Ar2 Step 1.
|
||||
// NSA Guide Step 3 (except point at infinity check).
|
||||
//
|
||||
// Note that the cofactor (h) is one since we only support prime-order
|
||||
// curves, so we can safely ignore the cofactor.
|
||||
//
|
||||
// It is impossible for the result to be the point at infinity because our
|
||||
// private key is in the range [1, n) and the curve has prime order and
|
||||
// `parse_uncompressed_point` verified that the peer public key is on the
|
||||
// curve and not at infinity. However, since the standards require the
|
||||
// check, we do it using `assert!`.
|
||||
//
|
||||
// NIST SP 800-56Ar2 defines "Destroy" thusly: "In this Recommendation, to
|
||||
// destroy is an action applied to a key or a piece of secret data. After
|
||||
// a key or a piece of secret data is destroyed, no information about its
|
||||
// value can be recovered." We interpret "destroy" somewhat liberally: we
|
||||
// assume that since we throw away the values to be destroyed, no
|
||||
// information about their values can be recovered. This doesn't meet the
|
||||
// NSA guide's explicit requirement to "zeroize" them though.
|
||||
// TODO: this only needs common scalar ops
|
||||
let my_private_key = private_key_as_scalar(private_key_ops, my_private_key);
|
||||
let product = private_key_ops.point_mul(&my_private_key, &peer_public_key);
|
||||
|
||||
// NIST SP 800-56Ar2 Steps 2, 3, 4, and 5.
|
||||
// NSA Guide Steps 3 (point at infinity check) and 4.
|
||||
//
|
||||
// Again, we have a pretty liberal interpretation of the NIST's spec's
|
||||
// "Destroy" that doesn't meet the NSA requirement to "zeroize."
|
||||
// `big_endian_affine_from_jacobian` verifies that the result is not at
|
||||
// infinity and also does an extra check to verify that the point is on
|
||||
// the curve.
|
||||
big_endian_affine_from_jacobian(private_key_ops, Some(out), None, &product)
|
||||
|
||||
// NSA Guide Step 5 & 6 are deferred to the caller. Again, we have a
|
||||
// pretty liberal interpretation of the NIST's spec's "Destroy" that
|
||||
// doesn't meet the NSA requirement to "zeroize."
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::super::ops;
|
||||
use crate::{agreement, ec, limb, test};
|
||||
|
||||
static SUPPORTED_SUITE_B_ALGS: [(&str, &agreement::Algorithm, &ec::Curve, &ops::CommonOps); 2] = [
|
||||
(
|
||||
"P-256",
|
||||
&agreement::ECDH_P256,
|
||||
&super::super::curve::P256,
|
||||
&super::super::ops::p256::COMMON_OPS,
|
||||
),
|
||||
(
|
||||
"P-384",
|
||||
&agreement::ECDH_P384,
|
||||
&super::super::curve::P384,
|
||||
&super::super::ops::p384::COMMON_OPS,
|
||||
),
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_agreement_suite_b_ecdh_generate() {
|
||||
// Generates a string of bytes 0x00...00, which will always result in
|
||||
// a scalar value of zero.
|
||||
let random_00 = test::rand::FixedByteRandom { byte: 0x00 };
|
||||
|
||||
// Generates a string of bytes 0xFF...FF, which will be larger than the
|
||||
// group order of any curve that is supported.
|
||||
let random_ff = test::rand::FixedByteRandom { byte: 0xff };
|
||||
|
||||
for &(_, alg, curve, ops) in SUPPORTED_SUITE_B_ALGS.iter() {
|
||||
// Test that the private key value zero is rejected and that
|
||||
// `generate` gives up after a while of only getting zeros.
|
||||
assert!(agreement::EphemeralPrivateKey::generate(alg, &random_00).is_err());
|
||||
|
||||
// Test that the private key value larger than the group order is
|
||||
// rejected and that `generate` gives up after a while of only
|
||||
// getting values larger than the group order.
|
||||
assert!(agreement::EphemeralPrivateKey::generate(alg, &random_ff).is_err());
|
||||
|
||||
// Test that a private key value exactly equal to the group order
|
||||
// is rejected and that `generate` gives up after a while of only
|
||||
// getting that value from the PRNG.
|
||||
let mut n_bytes = [0u8; ec::SCALAR_MAX_BYTES];
|
||||
let num_bytes = curve.elem_scalar_seed_len;
|
||||
limb::big_endian_from_limbs(&ops.n.limbs[..ops.num_limbs], &mut n_bytes[..num_bytes]);
|
||||
{
|
||||
let n_bytes = &mut n_bytes[..num_bytes];
|
||||
let rng = test::rand::FixedSliceRandom { bytes: n_bytes };
|
||||
assert!(agreement::EphemeralPrivateKey::generate(alg, &rng).is_err());
|
||||
}
|
||||
|
||||
// Test that a private key value exactly equal to the group order
|
||||
// minus 1 is accepted.
|
||||
let mut n_minus_1_bytes = n_bytes;
|
||||
{
|
||||
let n_minus_1_bytes = &mut n_minus_1_bytes[..num_bytes];
|
||||
n_minus_1_bytes[num_bytes - 1] -= 1;
|
||||
let rng = test::rand::FixedSliceRandom {
|
||||
bytes: n_minus_1_bytes,
|
||||
};
|
||||
let key = agreement::EphemeralPrivateKey::generate(alg, &rng).unwrap();
|
||||
assert_eq!(&n_minus_1_bytes[..], key.bytes());
|
||||
}
|
||||
|
||||
// Test that n + 1 also fails.
|
||||
let mut n_plus_1_bytes = n_bytes;
|
||||
{
|
||||
let n_plus_1_bytes = &mut n_plus_1_bytes[..num_bytes];
|
||||
n_plus_1_bytes[num_bytes - 1] += 1;
|
||||
let rng = test::rand::FixedSliceRandom {
|
||||
bytes: n_plus_1_bytes,
|
||||
};
|
||||
assert!(agreement::EphemeralPrivateKey::generate(alg, &rng).is_err());
|
||||
}
|
||||
|
||||
// Test recovery from initial RNG failure. The first value will be
|
||||
// n, then n + 1, then zero, the next value will be n - 1, which
|
||||
// will be accepted.
|
||||
{
|
||||
let bytes = [
|
||||
&n_bytes[..num_bytes],
|
||||
&n_plus_1_bytes[..num_bytes],
|
||||
&[0u8; ec::SCALAR_MAX_BYTES][..num_bytes],
|
||||
&n_minus_1_bytes[..num_bytes],
|
||||
];
|
||||
let rng = test::rand::FixedSliceSequenceRandom {
|
||||
bytes: &bytes,
|
||||
current: core::cell::UnsafeCell::new(0),
|
||||
};
|
||||
let key = agreement::EphemeralPrivateKey::generate(alg, &rng).unwrap();
|
||||
assert_eq!(&n_minus_1_bytes[..num_bytes], key.bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
zeroidc/vendor/ring/src/ec/suite_b/ecdsa.rs
vendored
Normal file
3
zeroidc/vendor/ring/src/ec/suite_b/ecdsa.rs
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
mod digest_scalar;
|
||||
pub mod signing;
|
||||
pub mod verification;
|
||||
131
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/digest_scalar.rs
vendored
Normal file
131
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/digest_scalar.rs
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! ECDSA Signatures using the P-256 and P-384 curves.
|
||||
|
||||
use crate::{
|
||||
digest,
|
||||
ec::suite_b::ops::*,
|
||||
limb::{self, LIMB_BYTES},
|
||||
};
|
||||
|
||||
/// Calculate the digest of `msg` using the digest algorithm `digest_alg`. Then
|
||||
/// convert the digest to a scalar in the range [0, n) as described in
|
||||
/// NIST's FIPS 186-4 Section 4.2. Note that this is one of the few cases where
|
||||
/// a `Scalar` is allowed to have the value zero.
|
||||
///
|
||||
/// NIST's FIPS 186-4 4.2 says "When the length of the output of the hash
|
||||
/// function is greater than N (i.e., the bit length of q), then the leftmost N
|
||||
/// bits of the hash function output block shall be used in any calculation
|
||||
/// using the hash function output during the generation or verification of a
|
||||
/// digital signature."
|
||||
///
|
||||
/// "Leftmost N bits" means "N most significant bits" because we interpret the
|
||||
/// digest as a bit-endian encoded integer.
|
||||
///
|
||||
/// The NSA guide instead vaguely suggests that we should convert the digest
|
||||
/// value to an integer and then reduce it mod `n`. However, real-world
|
||||
/// implementations (e.g. `digest_to_bn` in OpenSSL and `hashToInt` in Go) do
|
||||
/// what FIPS 186-4 says to do, not what the NSA guide suggests.
|
||||
///
|
||||
/// Why shifting the value right by at most one bit is sufficient: P-256's `n`
|
||||
/// has its 256th bit set; i.e. 2**255 < n < 2**256. Once we've truncated the
|
||||
/// digest to 256 bits and converted it to an integer, it will have a value
|
||||
/// less than 2**256. If the value is larger than `n` then shifting it one bit
|
||||
/// right will give a value less than 2**255, which is less than `n`. The
|
||||
/// analogous argument applies for P-384. However, it does *not* apply in
|
||||
/// general; for example, it doesn't apply to P-521.
|
||||
pub fn digest_scalar(ops: &ScalarOps, msg: digest::Digest) -> Scalar {
|
||||
digest_scalar_(ops, msg.as_ref())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn digest_bytes_scalar(ops: &ScalarOps, digest: &[u8]) -> Scalar {
|
||||
digest_scalar_(ops, digest)
|
||||
}
|
||||
|
||||
// This is a separate function solely so that we can test specific digest
|
||||
// values like all-zero values and values larger than `n`.
|
||||
fn digest_scalar_(ops: &ScalarOps, digest: &[u8]) -> Scalar {
|
||||
let cops = ops.common;
|
||||
let num_limbs = cops.num_limbs;
|
||||
let digest = if digest.len() > num_limbs * LIMB_BYTES {
|
||||
&digest[..(num_limbs * LIMB_BYTES)]
|
||||
} else {
|
||||
digest
|
||||
};
|
||||
|
||||
scalar_parse_big_endian_partially_reduced_variable_consttime(
|
||||
cops,
|
||||
limb::AllowZero::Yes,
|
||||
untrusted::Input::from(digest),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::digest_bytes_scalar;
|
||||
use crate::{
|
||||
digest,
|
||||
ec::suite_b::ops::*,
|
||||
limb::{self, LIMB_BYTES},
|
||||
test,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
test::run(
|
||||
test_file!("ecdsa_digest_scalar_tests.txt"),
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let curve_name = test_case.consume_string("Curve");
|
||||
let digest_name = test_case.consume_string("Digest");
|
||||
let input = test_case.consume_bytes("Input");
|
||||
let output = test_case.consume_bytes("Output");
|
||||
|
||||
let (ops, digest_alg) = match (curve_name.as_str(), digest_name.as_str()) {
|
||||
("P-256", "SHA256") => (&p256::PUBLIC_SCALAR_OPS, &digest::SHA256),
|
||||
("P-256", "SHA384") => (&p256::PUBLIC_SCALAR_OPS, &digest::SHA384),
|
||||
("P-384", "SHA256") => (&p384::PUBLIC_SCALAR_OPS, &digest::SHA256),
|
||||
("P-384", "SHA384") => (&p384::PUBLIC_SCALAR_OPS, &digest::SHA384),
|
||||
_ => {
|
||||
panic!("Unsupported curve+digest: {}+{}", curve_name, digest_name);
|
||||
}
|
||||
};
|
||||
|
||||
let num_limbs = ops.public_key_ops.common.num_limbs;
|
||||
assert_eq!(input.len(), digest_alg.output_len);
|
||||
assert_eq!(
|
||||
output.len(),
|
||||
ops.public_key_ops.common.num_limbs * LIMB_BYTES
|
||||
);
|
||||
|
||||
let expected = scalar_parse_big_endian_variable(
|
||||
ops.public_key_ops.common,
|
||||
limb::AllowZero::Yes,
|
||||
untrusted::Input::from(&output),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let actual = digest_bytes_scalar(ops.scalar_ops, &input);
|
||||
|
||||
assert_eq!(actual.limbs[..num_limbs], expected.limbs[..num_limbs]);
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
BIN
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecPublicKey_p256_pkcs8_v1_template.der
vendored
Normal file
BIN
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecPublicKey_p256_pkcs8_v1_template.der
vendored
Normal file
Binary file not shown.
BIN
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecPublicKey_p384_pkcs8_v1_template.der
vendored
Normal file
BIN
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecPublicKey_p384_pkcs8_v1_template.der
vendored
Normal file
Binary file not shown.
82
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecdsa_digest_scalar_tests.txt
vendored
Normal file
82
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecdsa_digest_scalar_tests.txt
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
# Test vectors for the conversion of digest values to scalars.
|
||||
|
||||
# Minimum Digest Values.
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Input = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
Output = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA384
|
||||
Input = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
Output = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA256
|
||||
Input = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
Output = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Input = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
Output = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
# The truncated digest value is equal to n - 1 (not possible when digest is
|
||||
# shorter than the curve's scalars).
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Input = FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550
|
||||
Output = FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA384
|
||||
Input = FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63255000000000000000000000000000000000
|
||||
Output = FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Input = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52972
|
||||
Output = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52972
|
||||
|
||||
# The truncated digest value is equal to n (not possible when digest is shorter
|
||||
# than the curve's scalars).
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Input = FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551
|
||||
Output = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA384
|
||||
Input = FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63255100000000000000000000000000000000
|
||||
Output = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Input = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973
|
||||
Output = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
|
||||
# Maximum digest values.
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Input = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
Output = 00000000FFFFFFFF00000000000000004319055258E8617B0C46353D039CDAAE
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA384
|
||||
Input = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
Output = 00000000FFFFFFFF00000000000000004319055258E8617B0C46353D039CDAAE
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA256
|
||||
Input = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
Output = 00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Input = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
Output = 000000000000000000000000000000000000000000000000389CB27E0BC8D220A7E5F24DB74F58851313E695333AD68C
|
||||
18
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecdsa_sign_asn1_tests.txt
vendored
Normal file
18
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecdsa_sign_asn1_tests.txt
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# Tests from NIST CAVP 186-4 ECDSA2VS Test Vectors, Signature Generation Test
|
||||
# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
|
||||
#
|
||||
# CAVS 11.2
|
||||
# "SigVer" information for "ecdsa_values"
|
||||
# Curves/SHAs selected: P-224,SHA-224 P-224,SHA-256 P-224,SHA-384 P-224,SHA-512 P-256,SHA-224 P-256,SHA-256 P-256,SHA-384 P-256,SHA-512 P-384,SHA-224 P-384,SHA-256 P-384,SHA-384 P-384,SHA-512 P-521,SHA-224 P-521,SHA-256 P-521,SHA-384 P-521,SHA-512 K-233,SHA-224 K-233,SHA-256 K-233,SHA-384 K-233,SHA-512 K-283,SHA-224 K-283,SHA-256 K-283,SHA-384 K-283,SHA-512 K-409,SHA-224 K-409,SHA-256 K-409,SHA-384 K-409,SHA-512 K-571,SHA-224 K-571,SHA-256 K-571,SHA-384 K-571,SHA-512 B-233,SHA-224 B-233,SHA-256 B-233,SHA-384 B-233,SHA-512 B-283,SHA-224 B-283,SHA-256 B-283,SHA-384 B-283,SHA-512 B-409,SHA-224 B-409,SHA-256 B-409,SHA-384 B-409,SHA-512 BB-571,SHA-224 B-571,SHA-256 B-571,SHA-384 B-571,SHA-512
|
||||
# Generated on Tue Aug 16 15:27:42 2011
|
||||
|
||||
# [P-256,SHA-256]
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8
|
||||
d = 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464
|
||||
Q = 041ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9
|
||||
k = 94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de
|
||||
Sig = 3046022100f3ac8061b514795b8843e3d6629527ed2afd6b1f6a555a7acabb5e6f79c8c2ac0221008bf77819ca05a6b2786c76262bf7371cef97b218e96f175a3ccdda2acc058903
|
||||
|
||||
251
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecdsa_sign_fixed_tests.txt
vendored
Normal file
251
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/ecdsa_sign_fixed_tests.txt
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
# Tests from NIST CAVP 186-4 ECDSA2VS Test Vectors, Signature Generation Test
|
||||
# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
|
||||
#
|
||||
# CAVS 11.2
|
||||
# "SigVer" information for "ecdsa_values"
|
||||
# Curves/SHAs selected: P-224,SHA-224 P-224,SHA-256 P-224,SHA-384 P-224,SHA-512 P-256,SHA-224 P-256,SHA-256 P-256,SHA-384 P-256,SHA-512 P-384,SHA-224 P-384,SHA-256 P-384,SHA-384 P-384,SHA-512 P-521,SHA-224 P-521,SHA-256 P-521,SHA-384 P-521,SHA-512 K-233,SHA-224 K-233,SHA-256 K-233,SHA-384 K-233,SHA-512 K-283,SHA-224 K-283,SHA-256 K-283,SHA-384 K-283,SHA-512 K-409,SHA-224 K-409,SHA-256 K-409,SHA-384 K-409,SHA-512 K-571,SHA-224 K-571,SHA-256 K-571,SHA-384 K-571,SHA-512 B-233,SHA-224 B-233,SHA-256 B-233,SHA-384 B-233,SHA-512 B-283,SHA-224 B-283,SHA-256 B-283,SHA-384 B-283,SHA-512 B-409,SHA-224 B-409,SHA-256 B-409,SHA-384 B-409,SHA-512 BB-571,SHA-224 B-571,SHA-256 B-571,SHA-384 B-571,SHA-512
|
||||
# Generated on Tue Aug 16 15:27:42 2011
|
||||
|
||||
# [P-256,SHA-256]
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8
|
||||
d = 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464
|
||||
Q = 041ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9
|
||||
k = 94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de
|
||||
Sig = f3ac8061b514795b8843e3d6629527ed2afd6b1f6a555a7acabb5e6f79c8c2ac8bf77819ca05a6b2786c76262bf7371cef97b218e96f175a3ccdda2acc058903
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1
|
||||
d = 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813
|
||||
Q = 04e266ddfdc12668db30d4ca3e8f7749432c416044f2d2b8c10bf3d4012aeffa8abfa86404a2e9ffe67d47c587ef7a97a7f456b863b4d02cfc6928973ab5b1cb39
|
||||
k = 6d3e71882c3b83b156bb14e0ab184aa9fb728068d3ae9fac421187ae0b2f34c6
|
||||
Sig = 976d3a4e9d23326dc0baa9fa560b7c4e53f42864f508483a6473b6a11079b2db1b766e9ceb71ba6c01dcd46e0af462cd4cfa652ae5017d4555b8eeefe36e1932
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee
|
||||
d = e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef
|
||||
Q = 0474ccd8a62fba0e667c50929a53f78c21b8ff0c3c737b0b40b1750b2302b0bde829074e21f3a0ef88b9efdf10d06aa4c295cc1671f758ca0e4cd108803d0f2614
|
||||
k = ad5e887eb2b380b8d8280ad6e5ff8a60f4d26243e0124c2f31a297b5d0835de2
|
||||
Sig = 35fb60f5ca0f3ca08542fb3cc641c8263a2cab7a90ee6a5e1583fac2bb6f6bd1ee59d81bc9db1055cc0ed97b159d8784af04e98511d0a9a407b99bb292572e96
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30
|
||||
d = a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07
|
||||
Q = 04322f80371bf6e044bc49391d97c1714ab87f990b949bc178cb7c43b7c22d89e13c15d54a5cc6b9f09de8457e873eb3deb1fceb54b0b295da6050294fae7fd999
|
||||
k = 24fc90e1da13f17ef9fe84cc96b9471ed1aaac17e3a4bae33a115df4e5834f18
|
||||
Sig = d7c562370af617b581c84a2468cc8bd50bb1cbf322de41b7887ce07c0e5884cab46d9f2d8c4bf83546ff178f1d78937c008d64e8ecc5cbb825cb21d94d670d89
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7
|
||||
d = 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d
|
||||
Q = 041bcec4570e1ec2436596b8ded58f60c3b1ebc6a403bc5543040ba829630572448af62a4c683f096b28558320737bf83b9959a46ad2521004ef74cf85e67494e1
|
||||
k = 5d833e8d24cc7a402d7ee7ec852a3587cddeb48358cea71b0bedb8fabe84e0c4
|
||||
Sig = 18caaf7b663507a8bcd992b836dec9dc5703c080af5e51dfa3a9a7c38718260477c68928ac3b88d985fb43fb615fb7ff45c18ba5c81af796c613dfa98352d29c
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71
|
||||
d = 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d
|
||||
Q = 04a32e50be3dae2c8ba3f5e4bdae14cf7645420d425ead94036c22dd6c4fc59e00d623bf641160c289d6742c6257ae6ba574446dd1d0e74db3aaa80900b78d4ae9
|
||||
k = e18f96f84dfa2fd3cdfaec9159d4c338cd54ad314134f0b31e20591fc238d0ab
|
||||
Sig = 8524c5024e2d9a73bde8c72d9129f57873bbad0ed05215a372a84fdbc78f2e68d18c2caf3b1072f87064ec5e8953f51301cada03469c640244760328eb5a05cb
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b
|
||||
d = 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab
|
||||
Q = 048bcfe2a721ca6d753968f564ec4315be4857e28bef1908f61a366b1f03c974790f67576a30b8e20d4232d8530b52fb4c89cbc589ede291e499ddd15fe870ab96
|
||||
k = 295544dbb2da3da170741c9b2c6551d40af7ed4e891445f11a02b66a5c258a77
|
||||
Sig = c5a186d72df452015480f7f338970bfe825087f05c0088d95305f87aacc9b25484a58f9e9d9e735344b316b1aa1ab5185665b85147dc82d92e969d7bee31ca30
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b
|
||||
d = 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a
|
||||
Q = 04a88bc8430279c8c0400a77d751f26c0abc93e5de4ad9a4166357952fe041e7672d365a1eef25ead579cc9a069b6abc1b16b81c35f18785ce26a10ba6d1381185
|
||||
k = 7c80fd66d62cc076cef2d030c17c0a69c99611549cb32c4ff662475adbe84b22
|
||||
Sig = 9d0c6afb6df3bced455b459cc21387e14929392664bb8741a3693a1795ca6902d7f9ddd191f1f412869429209ee3814c75c72fa46a9cccf804a2f5cc0b7e739f
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8
|
||||
d = 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881
|
||||
Q = 041bc487570f040dc94196c9befe8ab2b6de77208b1f38bdaae28f9645c4d2bc3aec81602abd8345e71867c8210313737865b8aa186851e1b48eaca140320f5d8f
|
||||
k = 2e7625a48874d86c9e467f890aaa7cd6ebdf71c0102bfdcfa24565d6af3fdce9
|
||||
Sig = 2f9e2b4e9f747c657f705bffd124ee178bbc5391c86d056717b140c153570fd9f5413bfd85949da8d83de83ab0d19b2986613e224d1901d76919de23ccd03199
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e
|
||||
d = f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308
|
||||
Q = 04b8188bd68701fc396dab53125d4d28ea33a91daf6d21485f4770f6ea8c565dde423f058810f277f8fe076f6db56e9285a1bf2c2a1dae145095edd9c04970bc4a
|
||||
k = 62f8665fd6e26b3fa069e85281777a9b1f0dfd2c0b9f54a086d0c109ff9fd615
|
||||
Sig = 1cc628533d0004b2b20e7f4baad0b8bb5e0673db159bbccf92491aef61fc9620880e0bbf82a8cf818ed46ba03cf0fc6c898e36fca36cc7fdb1d2db7503634430
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a
|
||||
d = b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906
|
||||
Q = 0451f99d2d52d4a6e734484a018b7ca2f895c2929b6754a3a03224d07ae61166ce4737da963c6ef7247fb88d19f9b0c667cac7fe12837fdab88c66f10d3c14cad1
|
||||
k = 72b656f6b35b9ccbc712c9f1f3b1a14cbbebaec41c4bca8da18f492a062d6f6f
|
||||
Sig = 9886ae46c1415c3bc959e82b760ad760aab66885a84e620aa339fdf102465c422bf3a80bc04faa35ebecc0f4864ac02d349f6f126e0f988501b8d3075409a26c
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4
|
||||
d = d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7
|
||||
Q = 048fb287f0202ad57ae841aea35f29b2e1d53e196d0ddd9aec24813d64c0922fb71f6daff1aa2dd2d6d3741623eecb5e7b612997a1039aab2e5cf2de969cfea573
|
||||
k = d926fe10f1bfd9855610f4f5a3d666b1a149344057e35537373372ead8b1a778
|
||||
Sig = 490efd106be11fc365c7467eb89b8d39e15d65175356775deab211163c2504cb644300fc0da4d40fb8c6ead510d14f0bd4e1321a469e9c0a581464c7186b7aa7
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7
|
||||
d = b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c
|
||||
Q = 0468229b48c2fe19d3db034e4c15077eb7471a66031f28a980821873915298ba76303e8ee3742a893f78b810991da697083dd8f11128c47651c27a56740a80c24c
|
||||
k = e158bf4a2d19a99149d9cdb879294ccb7aaeae03d75ddd616ef8ae51a6dc1071
|
||||
Sig = e67a9717ccf96841489d6541f4f6adb12d17b59a6bef847b6183b8fcf16a32eb9ae6ba6d637706849a6a9fc388cf0232d85c26ea0d1fe7437adb48de58364333
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01
|
||||
d = 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1
|
||||
Q = 040a7dbb8bf50cb605eb2268b081f26d6b08e012f952c4b70a5a1e6e7d46af98bbf26dd7d799930062480849962ccf5004edcfd307c044f4e8f667c9baa834eeae
|
||||
k = 646fe933e96c3b8f9f507498e907fdd201f08478d0202c752a7c2cfebf4d061a
|
||||
Sig = b53ce4da1aa7c0dc77a1896ab716b921499aed78df725b1504aba1597ba0c64bd7c246dc7ad0e67700c373edcfdd1c0a0495fc954549ad579df6ed1438840851
|
||||
|
||||
Curve = P-256
|
||||
Digest = SHA256
|
||||
Msg = 21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34
|
||||
d = 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1
|
||||
Q = 04105d22d9c626520faca13e7ced382dcbe93498315f00cc0ac39c4821d0d737376c47f3cbbfa97dfcebe16270b8c7d5d3a5900b888c42520d751e8faf3b401ef4
|
||||
k = a6f463ee72c9492bc792fe98163112837aebd07bab7a84aaed05be64db3086f4
|
||||
Sig = 542c40a18140a6266d6f0286e24e9a7bad7650e72ef0e2131e629c076d9626634f7f65305e24a6bbb5cff714ba8f5a2cee5bdc89ba8d75dcbf21966ce38eb66f
|
||||
|
||||
# [P-384,SHA-384]
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe
|
||||
d = 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97
|
||||
Q = 04c2b47944fb5de342d03285880177ca5f7d0f2fcad7678cce4229d6e1932fcac11bfc3c3e97d942a3c56bf34123013dbf37257906a8223866eda0743c519616a76a758ae58aee81c5fd35fbf3a855b7754a36d4a0672df95d6c44a81cf7620c2d
|
||||
k = dcedabf85978e090f733c6e16646fa34df9ded6e5ce28c6676a00f58a25283db8885e16ce5bf97f917c81e1f25c9c771
|
||||
Sig = 50835a9251bad008106177ef004b091a1e4235cd0da84fff54542b0ed755c1d6f251609d14ecf18f9e1ddfe69b946e320475f3d30c6463b646e8d3bf2455830314611cbde404be518b14464fdb195fdcc92eb222e61f426a4a592c00a6a89721
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4
|
||||
d = 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528
|
||||
Q = 045d42d6301c54a438f65970bae2a098cbc567e98840006e356221966c86d82e8eca515bca850eaa3cd41f175f03a0cbfd4aef5a0ceece95d382bd70ab5ce1cb77408bae42b51a08816d5e5e1d3da8c18fcc95564a752730b0aabea983ccea4e2e
|
||||
k = 67ba379366049008593eac124f59ab017358892ee0c063d38f3758bb849fd25d867c3561563cac1532a323b228dc0890
|
||||
Sig = fb318f4cb1276282bb43f733a7fb7c567ce94f4d02924fc758635ab2d1107108bf159b85db080cdc3b30fbb5400016f3588e3d7af5da03eae255ecb1813100d95edc243476b724b22db8e85377660d7645ddc1c2c2ee4eaea8b683dbe22f86ca
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf
|
||||
d = b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6
|
||||
Q = 0444ffb2a3a95e12d87c72b5ea0a8a7cb89f56b3bd46342b2303608d7216301c21b5d2921d80b6628dc512ccb84e2fc278e4c1002f1828abaec768cadcb7cf42fbf93b1709ccae6df5b134c41fae2b9a188bfbe1eccff0bd348517d7227f2071a6
|
||||
k = 229e67638f712f57bea4c2b02279d5ccad1e7c9e201c77f6f01aeb81ea90e62b44b2d2107fd66d35e56608fff65e28e4
|
||||
Sig = b11db592e4ebc75b6472b879b1d8ce57452c615aef20f67a280f8bca9b11a30ad4ac9d69541258c7dd5d0b4ab8dd7d494eb51db8004e46d438359abf060a9444616cb46b4f99c9a05b53ba6df02e914c9c0b6cc3a9791d804d2e4c0984dab1cc
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a
|
||||
d = de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976
|
||||
Q = 04f1fabafc01fec7e96d982528d9ef3a2a18b7fe8ae0fa0673977341c7ae4ae8d8d3d67420343d013a984f5f61da29ae381a31cf902c46343d01b2ebb614bc789c313b5f91f9302ad9418e9c797563e2fa3d44500f47b4e26ad8fdec1a816d1dcf
|
||||
k = fc5940e661542436f9265c34bce407eff6364bd471aa79b90c906d923e15c9ed96eea4e86f3238ea86161d13b7d9359d
|
||||
Sig = c2fbdd6a56789024082173725d797ef9fd6accb6ae664b7260f9e83cb8ab2490428c8b9c52e153612295432fec4d59cd8056c5bb57f41f73082888b234fcda320a33250b5da012ba1fdb4924355ae679012d81d2c08fc0f8634c708a4833232f
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc
|
||||
d = 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc
|
||||
Q = 041950166989164cbfd97968c7e8adb6fbca1873ebef811ea259eb48b7d584627f0e6d6c64defe23cbc95236505a252aa141ef424b5cb076d4e32accd9250ea75fcf4ffd81814040c050d58c0a29b06be11edf67c911b403e418b7277417e52906
|
||||
k = e56904028226eb04f8d071e3f9cefec91075a81ca0fa87b44cae148fe1ce9827b5d1910db2336d0eb9813ddba3e4d7b5
|
||||
Sig = c38ef30f55624e8935680c29f8c24824877cf48ffc0ef015e62de1068893353030d1193bf9d34237d7ce6ba92c98b0fe651b8c3d5c9d5b936d300802a06d82ad54f7b1ba4327b2f031c0c5b0cb215ad4354edc7f932d934e877dfa1cf51b13fe
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d
|
||||
d = 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2
|
||||
Q = 042e01c5b59e619e00b79060a1e8ef695472e23bf9a511fc3d5ed77a334a242557098e40972713732c5291c97adf9cf2cf563e3fe4ad807e803b9e961b08da4dde4cea8925649da0d93221ce4cdceabc6a1db7612180a8c6bef3579c65539b97e9
|
||||
k = 03d23f1277b949cb6380211ad9d338e6f76c3eedac95989b91d0243cfb734a54b19bca45a5d13d6a4b9f815d919eea77
|
||||
Sig = abab65308f0b79c4f3a9ff28dd490acb0c320434094cef93e75adfe17e5820dc1f77544cfaaacdc8cf9ac8b38e174bef11b783d879a6de054b316af7d56e526c3dce96c85289122e3ad927cfa77bfc50b4a96c97f85b1b8221be2df083ff58fb
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416
|
||||
d = ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1
|
||||
Q = 0451c78c979452edd53b563f63eb3e854a5b23e87f1b2103942b65f77d024471f75c8ce1cc0dfef83292b368112aa5126e313e6aaf09caa3ba30f13072b2134878f14a4a01ee86326cccbff3d079b4df097dc57985e8c8c834a10cb9d766169366
|
||||
k = c3de91dbe4f777698773da70dd610ef1a7efe4dc00d734399c7dd100728006a502822a5a7ff9129ffd8adf6c1fc1211a
|
||||
Sig = f4f477855819ad8b1763f53691b76afbc4a31a638b1e08c293f9bcd55decf797f9913ca128d4b45b2e2ea3e82c6cf5657c26be29569ef95480a6d0c1af49dc10a51a0a8931345e48c0c39498bfb94d62962980b56143a7b41a2fddc8794c1b7f
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2
|
||||
d = adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6
|
||||
Q = 04ef948daae68242330a7358ef73f23b56c07e37126266db3fa6eea233a04a9b3e4915233dd6754427cd4b71b75854077d009453ef1828eaff9e17c856d4fc1895ab60051312c3e1db1e3766566438b2990cbf9945c2545619e3e0145bc6a79004
|
||||
k = a2da3fae2e6da3cf11b49861afb34fba357fea89f54b35ce5ed7434ae09103fe53e2be75b93fc579fedf919f6d5e407e
|
||||
Sig = dda994b9c428b57e9f8bbaebba0d682e3aac6ed828e3a1e99a7fc4c804bff8df151137f539c7389d80e23d9f3ee497bfa0d6b10ceffd0e1b29cf784476f9173ba6ecd2cfc7929725f2d6e24e0db5a4721683640eaa2bbe151fb57560f9ce594b
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed
|
||||
d = 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d
|
||||
Q = 045709ec4305a9c3271c304face6c148142490b827a73a4c17affcfd01fffd7eaa65d2fdedfa2419fc64ed910823513fafb083cda1cf3be6371b6c06e729ea6299213428db57119347247ec1fcd44204386cc0bca3f452d9d864b39efbfc89d6b2
|
||||
k = 3c90cc7b6984056f570542a51cbe497ce4c11aeae8fc35e8fd6a0d9adeb650e8644f9d1d5e4341b5adc81e27f284c08f
|
||||
Sig = d13646895afb1bfd1953551bb922809c95ad65d6abe94eb3719c899aa1f6dba6b01222c7f283900fe98628b7597b6ea64a9a38afda04c0a6b0058943b679bd02205b14d0f3d49b8f31aac289129780cdb1c555def8c3f9106b478729e0c7efaa
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26
|
||||
d = e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7
|
||||
Q = 0406c037a0cbf43fdf335dff33de06d34348405353f9fdf2ce1361efba30fb204aea9dbd2e30da0a10fd2d876188371be6360d38f3940e34679204b98fbf70b8a4d97f25443e46d0807ab634ed5891ad864dd7703557aa933cd380e26eea662a43
|
||||
k = 32386b2593c85e877b70e5e5495936f65dc49553caef1aa6cc14d9cd370c442a0ccfab4c0da9ec311b67913b1b575a9d
|
||||
Sig = 5886078d3495767e330c7507b7ca0fa07a50e59912a416d89f0ab1aa4e88153d6eaf00882d1b4aa64153153352d853b52cc10023bf1bf8ccfd14b06b82cc2114449a352389c8ff9f6f78cdc4e32bde69f3869da0e17f691b329682ae7a36e1aa
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271
|
||||
d = d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca
|
||||
Q = 0449a1c631f31cf5c45b2676b1f130cbf9be683d0a50dffae0d147c1e9913ab1090c6529a84f47ddc7cf025921b771355a1e207eece62f2bcc6bdabc1113158145170be97469a2904eaaa93aad85b86a19719207f3e423051f5b9cbbe2754eefcb
|
||||
k = 78613c570c8d33b7dd1bd1561d87e36282e8cf4843e7c344a2b2bb6a0da94756d670eeaffe434f7ae7c780f7cf05ca08
|
||||
Sig = 66f92b39aa3f4aeb9e2dc03ac3855406fa3ebbab0a6c88a78d7a03482f0c9868d7b78bc081ede0947c7f37bf193074bae5c64ed98d7f3701193f25dd237d59c91c0da6e26215e0889d82e6d3e416693f8d58843cf30ab10ab8d0edd9170b53ad
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0
|
||||
d = 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d
|
||||
Q = 0470a0f16b6c61172659b027ed19b18fd8f57bd28dc0501f207bd6b0bb065b5671cf3dd1ed13d388dcf6ccc766597aa6044f845bf01c3c3f6126a7368c3454f51425801ee0b72e63fb6799b4420bfdebe3e37c7246db627cc82c09654979c700bb
|
||||
k = 28096ababe29a075fbdf894709a20d0fdedb01ed3eeacb642a33a0da6aed726e13caf6cf206792ec359f0c9f9b567552
|
||||
Sig = ee2923f9b9999ea05b5e57f505bed5c6ba0420def42c6fa90eef7a6ef770786525546de27cdeb2f8586f8f29fb4ee67c50ef923fb217c4cf65a48b94412fda430fac685f0da7bd574557c6c50f5b22e0c8354d99f2c2f2c2691f252f93c7d84a
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663
|
||||
d = 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368
|
||||
Q = 04cadbacef4406099316db2ce3206adc636c2bb0a835847ed7941efb02862472f3150338f13f4860d47f39b7e098f0a390752ad0f22c9c264336cde11bbc95d1816ed4d1b1500db6b8dce259a42832e613c31178c2c7995206a62e201ba108f570
|
||||
k = 7b69c5d5b4d05c9950dc94c27d58403b4c52c004b80a80418ad3a89aabc5d34f21926729e76afd280cc8ee88c9805a2a
|
||||
Sig = db054addb6161ee49c6ce2e4d646d7670754747b6737ca8516e9d1e87859937c3ef9b1d2663e10d7e4bd00ec85b7a97afcc504e0f00ef29587e4bc22faada4db30e2cb1ac552680a65785ae87beb666c792513f2be7a3180fc544296841a0e27
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b
|
||||
d = ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283
|
||||
Q = 0433093a0568757e8b58df5b72ea5fe5bf26e6f7aeb541b4c6a8c189c93721749bcaceccf2982a2f0702586a9f812fc66febe320d09e1f0662189d50b85a20403b821ac0d000afdbf66a0a33f304726c69e354d81c50b94ba3a5250efc31319cd1
|
||||
k = d9b4cd1bdfa83e608289634dbfcee643f07315baf743fc91922880b55a2feda3b38ddf6040d3ba10985cd1285fc690d5
|
||||
Sig = 009c74063e206a4259b53decff5445683a03f44fa67252b76bd3581081c714f882f882df915e97dbeab061fa8b3cc4e7d40e09d3468b46699948007e8f59845766dbf694b9c62066890dd055c0cb9a0caf0aa611fb9f466ad0bbb00dbe29d7eb
|
||||
|
||||
Curve = P-384
|
||||
Digest = SHA384
|
||||
Msg = 0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9
|
||||
d = e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb
|
||||
Q = 04a39ac353ca787982c577aff1e8601ce192aa90fd0de4c0ed627f66a8b6f02ae51315543f72ffc1c48a7269b25e7c289a9064a507b66b340b6e0e0d5ffaa67dd20e6dafc0ea6a6faee1635177af256f9108a22e9edf736ab4ae8e96dc207b1fa9
|
||||
k = b094cb3a5c1440cfab9dc56d0ec2eff00f2110dea203654c70757254aa5912a7e73972e607459b1f4861e0b08a5cc763
|
||||
Sig = ee82c0f90501136eb0dc0e459ad17bf3be1b1c8b8d05c60068a9306a346326ff7344776a95f1f7e2e2cf9477130e735caf10b90f203af23b7500e070536e64629ba19245d6ef39aab57fcdb1b73c4c6bf7070c6263544633d3d358c12a178138
|
||||
597
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/signing.rs
vendored
Normal file
597
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/signing.rs
vendored
Normal file
@@ -0,0 +1,597 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! ECDSA Signatures using the P-256 and P-384 curves.
|
||||
|
||||
use super::digest_scalar::digest_scalar;
|
||||
use crate::{
|
||||
arithmetic::montgomery::*,
|
||||
cpu, digest,
|
||||
ec::{
|
||||
self,
|
||||
suite_b::{ops::*, private_key},
|
||||
},
|
||||
error,
|
||||
io::der,
|
||||
limb, pkcs8, rand, sealed, signature,
|
||||
};
|
||||
/// An ECDSA signing algorithm.
|
||||
pub struct EcdsaSigningAlgorithm {
|
||||
curve: &'static ec::Curve,
|
||||
private_scalar_ops: &'static PrivateScalarOps,
|
||||
private_key_ops: &'static PrivateKeyOps,
|
||||
digest_alg: &'static digest::Algorithm,
|
||||
pkcs8_template: &'static pkcs8::Template,
|
||||
format_rs: fn(ops: &'static ScalarOps, r: &Scalar, s: &Scalar, out: &mut [u8]) -> usize,
|
||||
id: AlgorithmID,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum AlgorithmID {
|
||||
ECDSA_P256_SHA256_FIXED_SIGNING,
|
||||
ECDSA_P384_SHA384_FIXED_SIGNING,
|
||||
ECDSA_P256_SHA256_ASN1_SIGNING,
|
||||
ECDSA_P384_SHA384_ASN1_SIGNING,
|
||||
}
|
||||
|
||||
derive_debug_via_id!(EcdsaSigningAlgorithm);
|
||||
|
||||
impl PartialEq for EcdsaSigningAlgorithm {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for EcdsaSigningAlgorithm {}
|
||||
|
||||
impl sealed::Sealed for EcdsaSigningAlgorithm {}
|
||||
|
||||
/// An ECDSA key pair, used for signing.
|
||||
pub struct EcdsaKeyPair {
|
||||
d: Scalar<R>,
|
||||
nonce_key: NonceRandomKey,
|
||||
alg: &'static EcdsaSigningAlgorithm,
|
||||
public_key: PublicKey,
|
||||
}
|
||||
|
||||
derive_debug_via_field!(EcdsaKeyPair, stringify!(EcdsaKeyPair), public_key);
|
||||
|
||||
impl EcdsaKeyPair {
|
||||
/// Generates a new key pair and returns the key pair serialized as a
|
||||
/// PKCS#8 document.
|
||||
///
|
||||
/// The PKCS#8 document will be a v1 `OneAsymmetricKey` with the public key
|
||||
/// included in the `ECPrivateKey` structure, as described in
|
||||
/// [RFC 5958 Section 2] and [RFC 5915]. The `ECPrivateKey` structure will
|
||||
/// not have a `parameters` field so the generated key is compatible with
|
||||
/// PKCS#11.
|
||||
///
|
||||
/// [RFC 5915]: https://tools.ietf.org/html/rfc5915
|
||||
/// [RFC 5958 Section 2]: https://tools.ietf.org/html/rfc5958#section-2
|
||||
pub fn generate_pkcs8(
|
||||
alg: &'static EcdsaSigningAlgorithm,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
) -> Result<pkcs8::Document, error::Unspecified> {
|
||||
let private_key = ec::Seed::generate(alg.curve, rng, cpu::features())?;
|
||||
let public_key = private_key.compute_public_key()?;
|
||||
Ok(pkcs8::wrap_key(
|
||||
&alg.pkcs8_template,
|
||||
private_key.bytes_less_safe(),
|
||||
public_key.as_ref(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Constructs an ECDSA key pair by parsing an unencrypted PKCS#8 v1
|
||||
/// id-ecPublicKey `ECPrivateKey` key.
|
||||
///
|
||||
/// The input must be in PKCS#8 v1 format. It must contain the public key in
|
||||
/// the `ECPrivateKey` structure; `from_pkcs8()` will verify that the public
|
||||
/// key and the private key are consistent with each other. The algorithm
|
||||
/// identifier must identify the curve by name; it must not use an
|
||||
/// "explicit" encoding of the curve. The `parameters` field of the
|
||||
/// `ECPrivateKey`, if present, must be the same named curve that is in the
|
||||
/// algorithm identifier in the PKCS#8 header.
|
||||
pub fn from_pkcs8(
|
||||
alg: &'static EcdsaSigningAlgorithm,
|
||||
pkcs8: &[u8],
|
||||
) -> Result<Self, error::KeyRejected> {
|
||||
let key_pair = ec::suite_b::key_pair_from_pkcs8(
|
||||
alg.curve,
|
||||
alg.pkcs8_template,
|
||||
untrusted::Input::from(pkcs8),
|
||||
cpu::features(),
|
||||
)?;
|
||||
let rng = rand::SystemRandom::new(); // TODO: make this a parameter.
|
||||
Self::new(alg, key_pair, &rng)
|
||||
}
|
||||
|
||||
/// Constructs an ECDSA key pair from the private key and public key bytes
|
||||
///
|
||||
/// The private key must encoded as a big-endian fixed-length integer. For
|
||||
/// example, a P-256 private key must be 32 bytes prefixed with leading
|
||||
/// zeros as needed.
|
||||
///
|
||||
/// The public key is encoding in uncompressed form using the
|
||||
/// Octet-String-to-Elliptic-Curve-Point algorithm in
|
||||
/// [SEC 1: Elliptic Curve Cryptography, Version 2.0].
|
||||
///
|
||||
/// This is intended for use by code that deserializes key pairs. It is
|
||||
/// recommended to use `EcdsaKeyPair::from_pkcs8()` (with a PKCS#8-encoded
|
||||
/// key) instead.
|
||||
///
|
||||
/// [SEC 1: Elliptic Curve Cryptography, Version 2.0]:
|
||||
/// http://www.secg.org/sec1-v2.pdf
|
||||
pub fn from_private_key_and_public_key(
|
||||
alg: &'static EcdsaSigningAlgorithm,
|
||||
private_key: &[u8],
|
||||
public_key: &[u8],
|
||||
) -> Result<Self, error::KeyRejected> {
|
||||
let key_pair = ec::suite_b::key_pair_from_bytes(
|
||||
alg.curve,
|
||||
untrusted::Input::from(private_key),
|
||||
untrusted::Input::from(public_key),
|
||||
cpu::features(),
|
||||
)?;
|
||||
let rng = rand::SystemRandom::new(); // TODO: make this a parameter.
|
||||
Self::new(alg, key_pair, &rng)
|
||||
}
|
||||
|
||||
fn new(
|
||||
alg: &'static EcdsaSigningAlgorithm,
|
||||
key_pair: ec::KeyPair,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
) -> Result<Self, error::KeyRejected> {
|
||||
let (seed, public_key) = key_pair.split();
|
||||
let d = private_key::private_key_as_scalar(alg.private_key_ops, &seed);
|
||||
let d = alg
|
||||
.private_scalar_ops
|
||||
.scalar_ops
|
||||
.scalar_product(&d, &alg.private_scalar_ops.oneRR_mod_n);
|
||||
|
||||
let nonce_key = NonceRandomKey::new(alg, &seed, rng)?;
|
||||
Ok(Self {
|
||||
d,
|
||||
nonce_key,
|
||||
alg,
|
||||
public_key: PublicKey(public_key),
|
||||
})
|
||||
}
|
||||
|
||||
/// Deprecated. Returns the signature of the `message` using a random nonce
|
||||
/// generated by `rng`.
|
||||
pub fn sign(
|
||||
&self,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
message: &[u8],
|
||||
) -> Result<signature::Signature, error::Unspecified> {
|
||||
// Step 4 (out of order).
|
||||
let h = digest::digest(self.alg.digest_alg, message);
|
||||
|
||||
// Incorporate `h` into the nonce to hedge against faulty RNGs. (This
|
||||
// is not an approved random number generator that is mandated in
|
||||
// the spec.)
|
||||
let nonce_rng = NonceRandom {
|
||||
key: &self.nonce_key,
|
||||
message_digest: &h,
|
||||
rng,
|
||||
};
|
||||
|
||||
self.sign_digest(h, &nonce_rng)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn sign_with_fixed_nonce_during_test(
|
||||
&self,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
message: &[u8],
|
||||
) -> Result<signature::Signature, error::Unspecified> {
|
||||
// Step 4 (out of order).
|
||||
let h = digest::digest(self.alg.digest_alg, message);
|
||||
|
||||
self.sign_digest(h, rng)
|
||||
}
|
||||
|
||||
/// Returns the signature of message digest `h` using a "random" nonce
|
||||
/// generated by `rng`.
|
||||
fn sign_digest(
|
||||
&self,
|
||||
h: digest::Digest,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
) -> Result<signature::Signature, error::Unspecified> {
|
||||
// NSA Suite B Implementer's Guide to ECDSA Section 3.4.1: ECDSA
|
||||
// Signature Generation.
|
||||
|
||||
// NSA Guide Prerequisites:
|
||||
//
|
||||
// Prior to generating an ECDSA signature, the signatory shall
|
||||
// obtain:
|
||||
//
|
||||
// 1. an authentic copy of the domain parameters,
|
||||
// 2. a digital signature key pair (d,Q), either generated by a
|
||||
// method from Appendix A.1, or obtained from a trusted third
|
||||
// party,
|
||||
// 3. assurance of the validity of the public key Q (see Appendix
|
||||
// A.3), and
|
||||
// 4. assurance that he/she/it actually possesses the associated
|
||||
// private key d (see [SP800-89] Section 6).
|
||||
//
|
||||
// The domain parameters are hard-coded into the source code.
|
||||
// `EcdsaKeyPair::generate_pkcs8()` can be used to meet the second
|
||||
// requirement; otherwise, it is up to the user to ensure the key pair
|
||||
// was obtained from a trusted private key. The constructors for
|
||||
// `EcdsaKeyPair` ensure that #3 and #4 are met subject to the caveats
|
||||
// in SP800-89 Section 6.
|
||||
|
||||
let ops = self.alg.private_scalar_ops;
|
||||
let scalar_ops = ops.scalar_ops;
|
||||
let cops = scalar_ops.common;
|
||||
let private_key_ops = self.alg.private_key_ops;
|
||||
|
||||
for _ in 0..100 {
|
||||
// XXX: iteration conut?
|
||||
// Step 1.
|
||||
let k = private_key::random_scalar(self.alg.private_key_ops, rng)?;
|
||||
let k_inv = scalar_ops.scalar_inv_to_mont(&k);
|
||||
|
||||
// Step 2.
|
||||
let r = private_key_ops.point_mul_base(&k);
|
||||
|
||||
// Step 3.
|
||||
let r = {
|
||||
let (x, _) = private_key::affine_from_jacobian(private_key_ops, &r)?;
|
||||
let x = cops.elem_unencoded(&x);
|
||||
elem_reduced_to_scalar(cops, &x)
|
||||
};
|
||||
if cops.is_zero(&r) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Step 4 is done by the caller.
|
||||
|
||||
// Step 5.
|
||||
let e = digest_scalar(scalar_ops, h);
|
||||
|
||||
// Step 6.
|
||||
let s = {
|
||||
let dr = scalar_ops.scalar_product(&self.d, &r);
|
||||
let e_plus_dr = scalar_sum(cops, &e, &dr);
|
||||
scalar_ops.scalar_product(&k_inv, &e_plus_dr)
|
||||
};
|
||||
if cops.is_zero(&s) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Step 7 with encoding.
|
||||
return Ok(signature::Signature::new(|sig_bytes| {
|
||||
(self.alg.format_rs)(scalar_ops, &r, &s, sig_bytes)
|
||||
}));
|
||||
}
|
||||
|
||||
Err(error::Unspecified)
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates an ECDSA nonce in a way that attempts to protect against a faulty
|
||||
/// `SecureRandom`.
|
||||
struct NonceRandom<'a> {
|
||||
key: &'a NonceRandomKey,
|
||||
message_digest: &'a digest::Digest,
|
||||
rng: &'a dyn rand::SecureRandom,
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for NonceRandom<'_> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("NonceRandom").finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl rand::sealed::SecureRandom for NonceRandom<'_> {
|
||||
fn fill_impl(&self, dest: &mut [u8]) -> Result<(), error::Unspecified> {
|
||||
// Use the same digest algorithm that will be used to digest the
|
||||
// message. The digest algorithm's output is exactly the right size;
|
||||
// this is checked below.
|
||||
//
|
||||
// XXX(perf): The single iteration will require two digest block
|
||||
// operations because the amount of data digested is larger than one
|
||||
// block.
|
||||
let digest_alg = self.key.0.algorithm();
|
||||
let mut ctx = digest::Context::new(digest_alg);
|
||||
|
||||
// Digest the randomized digest of the private key.
|
||||
let key = self.key.0.as_ref();
|
||||
ctx.update(key);
|
||||
|
||||
// The random value is digested between the key and the message so that
|
||||
// the key and the message are not directly digested in the same digest
|
||||
// block.
|
||||
assert!(key.len() <= digest_alg.block_len / 2);
|
||||
{
|
||||
let mut rand = [0u8; digest::MAX_BLOCK_LEN];
|
||||
let rand = &mut rand[..digest_alg.block_len - key.len()];
|
||||
assert!(rand.len() >= dest.len());
|
||||
self.rng.fill(rand)?;
|
||||
ctx.update(rand);
|
||||
}
|
||||
|
||||
ctx.update(self.message_digest.as_ref());
|
||||
|
||||
let nonce = ctx.finish();
|
||||
|
||||
// `copy_from_slice()` panics if the lengths differ, so we don't have
|
||||
// to separately assert that the lengths are the same.
|
||||
dest.copy_from_slice(nonce.as_ref());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> sealed::Sealed for NonceRandom<'a> {}
|
||||
|
||||
struct NonceRandomKey(digest::Digest);
|
||||
|
||||
impl NonceRandomKey {
|
||||
fn new(
|
||||
alg: &EcdsaSigningAlgorithm,
|
||||
seed: &ec::Seed,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
) -> Result<Self, error::KeyRejected> {
|
||||
let mut rand = [0; digest::MAX_OUTPUT_LEN];
|
||||
let rand = &mut rand[0..alg.curve.elem_scalar_seed_len];
|
||||
|
||||
// XXX: `KeyRejected` isn't the right way to model failure of the RNG,
|
||||
// but to fix that we'd need to break the API by changing the result type.
|
||||
// TODO: Fix the API in the next breaking release.
|
||||
rng.fill(rand)
|
||||
.map_err(|error::Unspecified| error::KeyRejected::rng_failed())?;
|
||||
|
||||
let mut ctx = digest::Context::new(alg.digest_alg);
|
||||
ctx.update(rand);
|
||||
ctx.update(seed.bytes_less_safe());
|
||||
Ok(NonceRandomKey(ctx.finish()))
|
||||
}
|
||||
}
|
||||
|
||||
impl signature::KeyPair for EcdsaKeyPair {
|
||||
type PublicKey = PublicKey;
|
||||
|
||||
fn public_key(&self) -> &Self::PublicKey {
|
||||
&self.public_key
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PublicKey(ec::PublicKey);
|
||||
|
||||
derive_debug_self_as_ref_hex_bytes!(PublicKey);
|
||||
|
||||
impl AsRef<[u8]> for PublicKey {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
fn format_rs_fixed(ops: &'static ScalarOps, r: &Scalar, s: &Scalar, out: &mut [u8]) -> usize {
|
||||
let scalar_len = ops.scalar_bytes_len();
|
||||
|
||||
let (r_out, rest) = out.split_at_mut(scalar_len);
|
||||
limb::big_endian_from_limbs(&r.limbs[..ops.common.num_limbs], r_out);
|
||||
|
||||
let (s_out, _) = rest.split_at_mut(scalar_len);
|
||||
limb::big_endian_from_limbs(&s.limbs[..ops.common.num_limbs], s_out);
|
||||
|
||||
2 * scalar_len
|
||||
}
|
||||
|
||||
fn format_rs_asn1(ops: &'static ScalarOps, r: &Scalar, s: &Scalar, out: &mut [u8]) -> usize {
|
||||
// This assumes `a` is not zero since neither `r` or `s` is allowed to be
|
||||
// zero.
|
||||
fn format_integer_tlv(ops: &ScalarOps, a: &Scalar, out: &mut [u8]) -> usize {
|
||||
let mut fixed = [0u8; ec::SCALAR_MAX_BYTES + 1];
|
||||
let fixed = &mut fixed[..(ops.scalar_bytes_len() + 1)];
|
||||
limb::big_endian_from_limbs(&a.limbs[..ops.common.num_limbs], &mut fixed[1..]);
|
||||
|
||||
// Since `a_fixed_out` is an extra byte long, it is guaranteed to start
|
||||
// with a zero.
|
||||
debug_assert_eq!(fixed[0], 0);
|
||||
|
||||
// There must be at least one non-zero byte since `a` isn't zero.
|
||||
let first_index = fixed.iter().position(|b| *b != 0).unwrap();
|
||||
|
||||
// If the first byte has its high bit set, it needs to be prefixed with 0x00.
|
||||
let first_index = if fixed[first_index] & 0x80 != 0 {
|
||||
first_index - 1
|
||||
} else {
|
||||
first_index
|
||||
};
|
||||
let value = &fixed[first_index..];
|
||||
|
||||
out[0] = der::Tag::Integer as u8;
|
||||
|
||||
// Lengths less than 128 are encoded in one byte.
|
||||
assert!(value.len() < 128);
|
||||
out[1] = value.len() as u8;
|
||||
|
||||
out[2..][..value.len()].copy_from_slice(&value);
|
||||
|
||||
2 + value.len()
|
||||
}
|
||||
|
||||
out[0] = der::Tag::Sequence as u8;
|
||||
let r_tlv_len = format_integer_tlv(ops, r, &mut out[2..]);
|
||||
let s_tlv_len = format_integer_tlv(ops, s, &mut out[2..][r_tlv_len..]);
|
||||
|
||||
// Lengths less than 128 are encoded in one byte.
|
||||
let value_len = r_tlv_len + s_tlv_len;
|
||||
assert!(value_len < 128);
|
||||
out[1] = value_len as u8;
|
||||
|
||||
2 + value_len
|
||||
}
|
||||
|
||||
/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the
|
||||
/// P-256 curve and SHA-256.
|
||||
///
|
||||
/// See "`ECDSA_*_FIXED` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P256_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm = EcdsaSigningAlgorithm {
|
||||
curve: &ec::suite_b::curve::P256,
|
||||
private_scalar_ops: &p256::PRIVATE_SCALAR_OPS,
|
||||
private_key_ops: &p256::PRIVATE_KEY_OPS,
|
||||
digest_alg: &digest::SHA256,
|
||||
pkcs8_template: &EC_PUBLIC_KEY_P256_PKCS8_V1_TEMPLATE,
|
||||
format_rs: format_rs_fixed,
|
||||
id: AlgorithmID::ECDSA_P256_SHA256_FIXED_SIGNING,
|
||||
};
|
||||
|
||||
/// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the
|
||||
/// P-384 curve and SHA-384.
|
||||
///
|
||||
/// See "`ECDSA_*_FIXED` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P384_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm = EcdsaSigningAlgorithm {
|
||||
curve: &ec::suite_b::curve::P384,
|
||||
private_scalar_ops: &p384::PRIVATE_SCALAR_OPS,
|
||||
private_key_ops: &p384::PRIVATE_KEY_OPS,
|
||||
digest_alg: &digest::SHA384,
|
||||
pkcs8_template: &EC_PUBLIC_KEY_P384_PKCS8_V1_TEMPLATE,
|
||||
format_rs: format_rs_fixed,
|
||||
id: AlgorithmID::ECDSA_P384_SHA384_FIXED_SIGNING,
|
||||
};
|
||||
|
||||
/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-256 curve and
|
||||
/// SHA-256.
|
||||
///
|
||||
/// See "`ECDSA_*_ASN1` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P256_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm = EcdsaSigningAlgorithm {
|
||||
curve: &ec::suite_b::curve::P256,
|
||||
private_scalar_ops: &p256::PRIVATE_SCALAR_OPS,
|
||||
private_key_ops: &p256::PRIVATE_KEY_OPS,
|
||||
digest_alg: &digest::SHA256,
|
||||
pkcs8_template: &EC_PUBLIC_KEY_P256_PKCS8_V1_TEMPLATE,
|
||||
format_rs: format_rs_asn1,
|
||||
id: AlgorithmID::ECDSA_P256_SHA256_ASN1_SIGNING,
|
||||
};
|
||||
|
||||
/// Signing of ASN.1 DER-encoded ECDSA signatures using the P-384 curve and
|
||||
/// SHA-384.
|
||||
///
|
||||
/// See "`ECDSA_*_ASN1` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P384_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm = EcdsaSigningAlgorithm {
|
||||
curve: &ec::suite_b::curve::P384,
|
||||
private_scalar_ops: &p384::PRIVATE_SCALAR_OPS,
|
||||
private_key_ops: &p384::PRIVATE_KEY_OPS,
|
||||
digest_alg: &digest::SHA384,
|
||||
pkcs8_template: &EC_PUBLIC_KEY_P384_PKCS8_V1_TEMPLATE,
|
||||
format_rs: format_rs_asn1,
|
||||
id: AlgorithmID::ECDSA_P384_SHA384_ASN1_SIGNING,
|
||||
};
|
||||
|
||||
static EC_PUBLIC_KEY_P256_PKCS8_V1_TEMPLATE: pkcs8::Template = pkcs8::Template {
|
||||
bytes: include_bytes!("ecPublicKey_p256_pkcs8_v1_template.der"),
|
||||
alg_id_range: core::ops::Range { start: 8, end: 27 },
|
||||
curve_id_index: 9,
|
||||
private_key_index: 0x24,
|
||||
};
|
||||
|
||||
static EC_PUBLIC_KEY_P384_PKCS8_V1_TEMPLATE: pkcs8::Template = pkcs8::Template {
|
||||
bytes: include_bytes!("ecPublicKey_p384_pkcs8_v1_template.der"),
|
||||
alg_id_range: core::ops::Range { start: 8, end: 24 },
|
||||
curve_id_index: 9,
|
||||
private_key_index: 0x23,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{signature, test};
|
||||
|
||||
#[test]
|
||||
fn signature_ecdsa_sign_fixed_test() {
|
||||
test::run(
|
||||
test_file!("ecdsa_sign_fixed_tests.txt"),
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let curve_name = test_case.consume_string("Curve");
|
||||
let digest_name = test_case.consume_string("Digest");
|
||||
let msg = test_case.consume_bytes("Msg");
|
||||
let d = test_case.consume_bytes("d");
|
||||
let q = test_case.consume_bytes("Q");
|
||||
let k = test_case.consume_bytes("k");
|
||||
|
||||
let expected_result = test_case.consume_bytes("Sig");
|
||||
|
||||
let alg = match (curve_name.as_str(), digest_name.as_str()) {
|
||||
("P-256", "SHA256") => &signature::ECDSA_P256_SHA256_FIXED_SIGNING,
|
||||
("P-384", "SHA384") => &signature::ECDSA_P384_SHA384_FIXED_SIGNING,
|
||||
_ => {
|
||||
panic!("Unsupported curve+digest: {}+{}", curve_name, digest_name);
|
||||
}
|
||||
};
|
||||
|
||||
let private_key =
|
||||
signature::EcdsaKeyPair::from_private_key_and_public_key(alg, &d, &q).unwrap();
|
||||
let rng = test::rand::FixedSliceRandom { bytes: &k };
|
||||
|
||||
let actual_result = private_key
|
||||
.sign_with_fixed_nonce_during_test(&rng, &msg)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(actual_result.as_ref(), &expected_result[..]);
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn signature_ecdsa_sign_asn1_test() {
|
||||
test::run(
|
||||
test_file!("ecdsa_sign_asn1_tests.txt"),
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let curve_name = test_case.consume_string("Curve");
|
||||
let digest_name = test_case.consume_string("Digest");
|
||||
let msg = test_case.consume_bytes("Msg");
|
||||
let d = test_case.consume_bytes("d");
|
||||
let q = test_case.consume_bytes("Q");
|
||||
let k = test_case.consume_bytes("k");
|
||||
|
||||
let expected_result = test_case.consume_bytes("Sig");
|
||||
|
||||
let alg = match (curve_name.as_str(), digest_name.as_str()) {
|
||||
("P-256", "SHA256") => &signature::ECDSA_P256_SHA256_ASN1_SIGNING,
|
||||
("P-384", "SHA384") => &signature::ECDSA_P384_SHA384_ASN1_SIGNING,
|
||||
_ => {
|
||||
panic!("Unsupported curve+digest: {}+{}", curve_name, digest_name);
|
||||
}
|
||||
};
|
||||
|
||||
let private_key =
|
||||
signature::EcdsaKeyPair::from_private_key_and_public_key(alg, &d, &q).unwrap();
|
||||
let rng = test::rand::FixedSliceRandom { bytes: &k };
|
||||
|
||||
let actual_result = private_key
|
||||
.sign_with_fixed_nonce_during_test(&rng, &msg)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(actual_result.as_ref(), &expected_result[..]);
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
344
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/verification.rs
vendored
Normal file
344
zeroidc/vendor/ring/src/ec/suite_b/ecdsa/verification.rs
vendored
Normal file
@@ -0,0 +1,344 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! ECDSA Signatures using the P-256 and P-384 curves.
|
||||
|
||||
use super::digest_scalar::digest_scalar;
|
||||
use crate::{
|
||||
arithmetic::montgomery::*,
|
||||
digest,
|
||||
ec::suite_b::{ops::*, public_key::*, verify_jacobian_point_is_on_the_curve},
|
||||
error,
|
||||
io::der,
|
||||
limb, sealed, signature,
|
||||
};
|
||||
|
||||
/// An ECDSA verification algorithm.
|
||||
pub struct EcdsaVerificationAlgorithm {
|
||||
ops: &'static PublicScalarOps,
|
||||
digest_alg: &'static digest::Algorithm,
|
||||
split_rs:
|
||||
for<'a> fn(
|
||||
ops: &'static ScalarOps,
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
)
|
||||
-> Result<(untrusted::Input<'a>, untrusted::Input<'a>), error::Unspecified>,
|
||||
id: AlgorithmID,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum AlgorithmID {
|
||||
ECDSA_P256_SHA256_ASN1,
|
||||
ECDSA_P256_SHA256_FIXED,
|
||||
ECDSA_P256_SHA384_ASN1,
|
||||
ECDSA_P384_SHA256_ASN1,
|
||||
ECDSA_P384_SHA384_ASN1,
|
||||
ECDSA_P384_SHA384_FIXED,
|
||||
}
|
||||
|
||||
derive_debug_via_id!(EcdsaVerificationAlgorithm);
|
||||
|
||||
impl signature::VerificationAlgorithm for EcdsaVerificationAlgorithm {
|
||||
fn verify(
|
||||
&self,
|
||||
public_key: untrusted::Input,
|
||||
msg: untrusted::Input,
|
||||
signature: untrusted::Input,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
let e = {
|
||||
// NSA Guide Step 2: "Use the selected hash function to compute H =
|
||||
// Hash(M)."
|
||||
let h = digest::digest(self.digest_alg, msg.as_slice_less_safe());
|
||||
|
||||
// NSA Guide Step 3: "Convert the bit string H to an integer e as
|
||||
// described in Appendix B.2."
|
||||
digest_scalar(self.ops.scalar_ops, h)
|
||||
};
|
||||
|
||||
self.verify_digest(public_key, e, signature)
|
||||
}
|
||||
}
|
||||
|
||||
impl EcdsaVerificationAlgorithm {
|
||||
/// This is intentionally not public.
|
||||
fn verify_digest(
|
||||
&self,
|
||||
public_key: untrusted::Input,
|
||||
e: Scalar,
|
||||
signature: untrusted::Input,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
// NSA Suite B Implementer's Guide to ECDSA Section 3.4.2.
|
||||
|
||||
let public_key_ops = self.ops.public_key_ops;
|
||||
let scalar_ops = self.ops.scalar_ops;
|
||||
|
||||
// NSA Guide Prerequisites:
|
||||
//
|
||||
// Prior to accepting a verified digital signature as valid the
|
||||
// verifier shall have:
|
||||
//
|
||||
// 1. assurance of the signatory’s claimed identity,
|
||||
// 2. an authentic copy of the domain parameters, (q, FR, a, b, SEED,
|
||||
// G, n, h),
|
||||
// 3. assurance of the validity of the public key, and
|
||||
// 4. assurance that the claimed signatory actually possessed the
|
||||
// private key that was used to generate the digital signature at
|
||||
// the time that the signature was generated.
|
||||
//
|
||||
// Prerequisites #1 and #4 are outside the scope of what this function
|
||||
// can do. Prerequisite #2 is handled implicitly as the domain
|
||||
// parameters are hard-coded into the source. Prerequisite #3 is
|
||||
// handled by `parse_uncompressed_point`.
|
||||
let peer_pub_key = parse_uncompressed_point(public_key_ops, public_key)?;
|
||||
|
||||
let (r, s) = signature.read_all(error::Unspecified, |input| {
|
||||
(self.split_rs)(scalar_ops, input)
|
||||
})?;
|
||||
|
||||
// NSA Guide Step 1: "If r and s are not both integers in the interval
|
||||
// [1, n − 1], output INVALID."
|
||||
let r = scalar_parse_big_endian_variable(public_key_ops.common, limb::AllowZero::No, r)?;
|
||||
let s = scalar_parse_big_endian_variable(public_key_ops.common, limb::AllowZero::No, s)?;
|
||||
|
||||
// NSA Guide Step 4: "Compute w = s**−1 mod n, using the routine in
|
||||
// Appendix B.1."
|
||||
let w = scalar_ops.scalar_inv_to_mont(&s);
|
||||
|
||||
// NSA Guide Step 5: "Compute u1 = (e * w) mod n, and compute
|
||||
// u2 = (r * w) mod n."
|
||||
let u1 = scalar_ops.scalar_product(&e, &w);
|
||||
let u2 = scalar_ops.scalar_product(&r, &w);
|
||||
|
||||
// NSA Guide Step 6: "Compute the elliptic curve point
|
||||
// R = (xR, yR) = u1*G + u2*Q, using EC scalar multiplication and EC
|
||||
// addition. If R is equal to the point at infinity, output INVALID."
|
||||
let product = twin_mul(self.ops.private_key_ops, &u1, &u2, &peer_pub_key);
|
||||
|
||||
// Verify that the point we computed is on the curve; see
|
||||
// `verify_affine_point_is_on_the_curve_scaled` for details on why. It
|
||||
// would be more secure to do the check on the affine coordinates if we
|
||||
// were going to convert to affine form (again, see
|
||||
// `verify_affine_point_is_on_the_curve_scaled` for details on why).
|
||||
// But, we're going to avoid converting to affine for performance
|
||||
// reasons, so we do the verification using the Jacobian coordinates.
|
||||
let z2 = verify_jacobian_point_is_on_the_curve(public_key_ops.common, &product)?;
|
||||
|
||||
// NSA Guide Step 7: "Compute v = xR mod n."
|
||||
// NSA Guide Step 8: "Compare v and r0. If v = r0, output VALID;
|
||||
// otherwise, output INVALID."
|
||||
//
|
||||
// Instead, we use Greg Maxwell's trick to avoid the inversion mod `q`
|
||||
// that would be necessary to compute the affine X coordinate.
|
||||
let x = public_key_ops.common.point_x(&product);
|
||||
fn sig_r_equals_x(
|
||||
ops: &PublicScalarOps,
|
||||
r: &Elem<Unencoded>,
|
||||
x: &Elem<R>,
|
||||
z2: &Elem<R>,
|
||||
) -> bool {
|
||||
let cops = ops.public_key_ops.common;
|
||||
let r_jacobian = cops.elem_product(z2, r);
|
||||
let x = cops.elem_unencoded(x);
|
||||
ops.elem_equals(&r_jacobian, &x)
|
||||
}
|
||||
let r = self.ops.scalar_as_elem(&r);
|
||||
if sig_r_equals_x(self.ops, &r, &x, &z2) {
|
||||
return Ok(());
|
||||
}
|
||||
if self.ops.elem_less_than(&r, &self.ops.q_minus_n) {
|
||||
let r_plus_n = self.ops.elem_sum(&r, &public_key_ops.common.n);
|
||||
if sig_r_equals_x(self.ops, &r_plus_n, &x, &z2) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
Err(error::Unspecified)
|
||||
}
|
||||
}
|
||||
|
||||
impl sealed::Sealed for EcdsaVerificationAlgorithm {}
|
||||
|
||||
fn split_rs_fixed<'a>(
|
||||
ops: &'static ScalarOps,
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
) -> Result<(untrusted::Input<'a>, untrusted::Input<'a>), error::Unspecified> {
|
||||
let scalar_len = ops.scalar_bytes_len();
|
||||
let r = input.read_bytes(scalar_len)?;
|
||||
let s = input.read_bytes(scalar_len)?;
|
||||
Ok((r, s))
|
||||
}
|
||||
|
||||
fn split_rs_asn1<'a>(
|
||||
_ops: &'static ScalarOps,
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
) -> Result<(untrusted::Input<'a>, untrusted::Input<'a>), error::Unspecified> {
|
||||
der::nested(input, der::Tag::Sequence, error::Unspecified, |input| {
|
||||
let r = der::positive_integer(input)?.big_endian_without_leading_zero_as_input();
|
||||
let s = der::positive_integer(input)?.big_endian_without_leading_zero_as_input();
|
||||
Ok((r, s))
|
||||
})
|
||||
}
|
||||
|
||||
fn twin_mul(
|
||||
ops: &PrivateKeyOps,
|
||||
g_scalar: &Scalar,
|
||||
p_scalar: &Scalar,
|
||||
p_xy: &(Elem<R>, Elem<R>),
|
||||
) -> Point {
|
||||
// XXX: Inefficient. TODO: implement interleaved wNAF multiplication.
|
||||
let scaled_g = ops.point_mul_base(g_scalar);
|
||||
let scaled_p = ops.point_mul(p_scalar, p_xy);
|
||||
ops.common.point_sum(&scaled_g, &scaled_p)
|
||||
}
|
||||
|
||||
/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the
|
||||
/// P-256 curve and SHA-256.
|
||||
///
|
||||
/// See "`ECDSA_*_FIXED` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P256_SHA256_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
|
||||
ops: &p256::PUBLIC_SCALAR_OPS,
|
||||
digest_alg: &digest::SHA256,
|
||||
split_rs: split_rs_fixed,
|
||||
id: AlgorithmID::ECDSA_P256_SHA256_FIXED,
|
||||
};
|
||||
|
||||
/// Verification of fixed-length (PKCS#11 style) ECDSA signatures using the
|
||||
/// P-384 curve and SHA-384.
|
||||
///
|
||||
/// See "`ECDSA_*_FIXED` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P384_SHA384_FIXED: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
|
||||
ops: &p384::PUBLIC_SCALAR_OPS,
|
||||
digest_alg: &digest::SHA384,
|
||||
split_rs: split_rs_fixed,
|
||||
id: AlgorithmID::ECDSA_P384_SHA384_FIXED,
|
||||
};
|
||||
|
||||
/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-256 curve
|
||||
/// and SHA-256.
|
||||
///
|
||||
/// See "`ECDSA_*_ASN1` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P256_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
|
||||
ops: &p256::PUBLIC_SCALAR_OPS,
|
||||
digest_alg: &digest::SHA256,
|
||||
split_rs: split_rs_asn1,
|
||||
id: AlgorithmID::ECDSA_P256_SHA256_ASN1,
|
||||
};
|
||||
|
||||
/// *Not recommended*. Verification of ASN.1 DER-encoded ECDSA signatures using
|
||||
/// the P-256 curve and SHA-384.
|
||||
///
|
||||
/// In most situations, P-256 should be used only with SHA-256 and P-384
|
||||
/// should be used only with SHA-384. However, in some cases, particularly TLS
|
||||
/// on the web, it is necessary to support P-256 with SHA-384 for compatibility
|
||||
/// with widely-deployed implementations that do not follow these guidelines.
|
||||
///
|
||||
/// See "`ECDSA_*_ASN1` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P256_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
|
||||
ops: &p256::PUBLIC_SCALAR_OPS,
|
||||
digest_alg: &digest::SHA384,
|
||||
split_rs: split_rs_asn1,
|
||||
id: AlgorithmID::ECDSA_P256_SHA384_ASN1,
|
||||
};
|
||||
|
||||
/// *Not recommended*. Verification of ASN.1 DER-encoded ECDSA signatures using
|
||||
/// the P-384 curve and SHA-256.
|
||||
///
|
||||
/// In most situations, P-256 should be used only with SHA-256 and P-384
|
||||
/// should be used only with SHA-384. However, in some cases, particularly TLS
|
||||
/// on the web, it is necessary to support P-256 with SHA-384 for compatibility
|
||||
/// with widely-deployed implementations that do not follow these guidelines.
|
||||
///
|
||||
/// See "`ECDSA_*_ASN1` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P384_SHA256_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
|
||||
ops: &p384::PUBLIC_SCALAR_OPS,
|
||||
digest_alg: &digest::SHA256,
|
||||
split_rs: split_rs_asn1,
|
||||
id: AlgorithmID::ECDSA_P384_SHA256_ASN1,
|
||||
};
|
||||
|
||||
/// Verification of ASN.1 DER-encoded ECDSA signatures using the P-384 curve
|
||||
/// and SHA-384.
|
||||
///
|
||||
/// See "`ECDSA_*_ASN1` Details" in `ring::signature`'s module-level
|
||||
/// documentation for more details.
|
||||
pub static ECDSA_P384_SHA384_ASN1: EcdsaVerificationAlgorithm = EcdsaVerificationAlgorithm {
|
||||
ops: &p384::PUBLIC_SCALAR_OPS,
|
||||
digest_alg: &digest::SHA384,
|
||||
split_rs: split_rs_asn1,
|
||||
id: AlgorithmID::ECDSA_P384_SHA384_ASN1,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
#[test]
|
||||
fn test_digest_based_test_vectors() {
|
||||
test::run(
|
||||
test_file!("../../../../crypto/fipsmodule/ecdsa/ecdsa_verify_tests.txt"),
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let curve_name = test_case.consume_string("Curve");
|
||||
|
||||
let public_key = {
|
||||
let mut public_key = Vec::new();
|
||||
public_key.push(0x04);
|
||||
public_key.extend(&test_case.consume_bytes("X"));
|
||||
public_key.extend(&test_case.consume_bytes("Y"));
|
||||
public_key
|
||||
};
|
||||
|
||||
let digest = test_case.consume_bytes("Digest");
|
||||
|
||||
let sig = {
|
||||
let mut sig = Vec::new();
|
||||
sig.extend(&test_case.consume_bytes("R"));
|
||||
sig.extend(&test_case.consume_bytes("S"));
|
||||
sig
|
||||
};
|
||||
|
||||
let invalid = test_case.consume_optional_string("Invalid");
|
||||
|
||||
let alg = match curve_name.as_str() {
|
||||
"P-256" => &ECDSA_P256_SHA256_FIXED,
|
||||
"P-384" => &ECDSA_P384_SHA384_FIXED,
|
||||
_ => {
|
||||
panic!("Unsupported curve: {}", curve_name);
|
||||
}
|
||||
};
|
||||
|
||||
let digest = super::super::digest_scalar::digest_bytes_scalar(
|
||||
&alg.ops.scalar_ops,
|
||||
&digest[..],
|
||||
);
|
||||
let actual_result = alg.verify_digest(
|
||||
untrusted::Input::from(&public_key[..]),
|
||||
digest,
|
||||
untrusted::Input::from(&sig[..]),
|
||||
);
|
||||
assert_eq!(actual_result.is_ok(), invalid.is_none());
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
1181
zeroidc/vendor/ring/src/ec/suite_b/ops.rs
vendored
Normal file
1181
zeroidc/vendor/ring/src/ec/suite_b/ops.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
120
zeroidc/vendor/ring/src/ec/suite_b/ops/elem.rs
vendored
Normal file
120
zeroidc/vendor/ring/src/ec/suite_b/ops/elem.rs
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
// Copyright 2017 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use crate::{
|
||||
arithmetic::montgomery::{Encoding, ProductEncoding},
|
||||
limb::{Limb, LIMB_BITS},
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
/// Elements of ℤ/mℤ for some modulus *m*. Elements are always fully reduced
|
||||
/// with respect to *m*; i.e. the 0 <= x < m for every value x.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Elem<M, E: Encoding> {
|
||||
// XXX: pub
|
||||
pub limbs: [Limb; MAX_LIMBS],
|
||||
|
||||
/// The modulus *m* for the ring ℤ/mℤ for which this element is a value.
|
||||
pub m: PhantomData<M>,
|
||||
|
||||
/// The number of Montgomery factors that need to be canceled out from
|
||||
/// `value` to get the actual value.
|
||||
pub encoding: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<M, E: Encoding> Elem<M, E> {
|
||||
// There's no need to convert `value` to the Montgomery domain since
|
||||
// 0 * R**2 (mod m) == 0, so neither the modulus nor the encoding are needed
|
||||
// as inputs for constructing a zero-valued element.
|
||||
pub fn zero() -> Self {
|
||||
Self {
|
||||
limbs: [0; MAX_LIMBS],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mul_mont<M, EA: Encoding, EB: Encoding>(
|
||||
f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
|
||||
a: &Elem<M, EA>,
|
||||
b: &Elem<M, EB>,
|
||||
) -> Elem<M, <(EA, EB) as ProductEncoding>::Output>
|
||||
where
|
||||
(EA, EB): ProductEncoding,
|
||||
{
|
||||
binary_op(f, a, b)
|
||||
}
|
||||
|
||||
// let r = f(a, b); return r;
|
||||
#[inline]
|
||||
pub fn binary_op<M, EA: Encoding, EB: Encoding, ER: Encoding>(
|
||||
f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
|
||||
a: &Elem<M, EA>,
|
||||
b: &Elem<M, EB>,
|
||||
) -> Elem<M, ER> {
|
||||
let mut r = Elem {
|
||||
limbs: [0; MAX_LIMBS],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
};
|
||||
unsafe { f(r.limbs.as_mut_ptr(), a.limbs.as_ptr(), b.limbs.as_ptr()) }
|
||||
r
|
||||
}
|
||||
|
||||
// a := f(a, b);
|
||||
#[inline]
|
||||
pub fn binary_op_assign<M, EA: Encoding, EB: Encoding>(
|
||||
f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
|
||||
a: &mut Elem<M, EA>,
|
||||
b: &Elem<M, EB>,
|
||||
) {
|
||||
unsafe { f(a.limbs.as_mut_ptr(), a.limbs.as_ptr(), b.limbs.as_ptr()) }
|
||||
}
|
||||
|
||||
// let r = f(a); return r;
|
||||
#[inline]
|
||||
pub fn unary_op<M, E: Encoding>(
|
||||
f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),
|
||||
a: &Elem<M, E>,
|
||||
) -> Elem<M, E> {
|
||||
let mut r = Elem {
|
||||
limbs: [0; MAX_LIMBS],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
};
|
||||
unsafe { f(r.limbs.as_mut_ptr(), a.limbs.as_ptr()) }
|
||||
r
|
||||
}
|
||||
|
||||
// a := f(a);
|
||||
#[inline]
|
||||
pub fn unary_op_assign<M, E: Encoding>(
|
||||
f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),
|
||||
a: &mut Elem<M, E>,
|
||||
) {
|
||||
unsafe { f(a.limbs.as_mut_ptr(), a.limbs.as_ptr()) }
|
||||
}
|
||||
|
||||
// a := f(a, a);
|
||||
#[inline]
|
||||
pub fn unary_op_from_binary_op_assign<M, E: Encoding>(
|
||||
f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
|
||||
a: &mut Elem<M, E>,
|
||||
) {
|
||||
unsafe { f(a.limbs.as_mut_ptr(), a.limbs.as_ptr(), a.limbs.as_ptr()) }
|
||||
}
|
||||
|
||||
pub const MAX_LIMBS: usize = (384 + (LIMB_BITS - 1)) / LIMB_BITS;
|
||||
382
zeroidc/vendor/ring/src/ec/suite_b/ops/p256.rs
vendored
Normal file
382
zeroidc/vendor/ring/src/ec/suite_b/ops/p256.rs
vendored
Normal file
@@ -0,0 +1,382 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::{
|
||||
elem::{binary_op, binary_op_assign},
|
||||
elem_sqr_mul, elem_sqr_mul_acc, Modulus, *,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
macro_rules! p256_limbs {
|
||||
[ $($limb:expr),+ ] => {
|
||||
limbs![$($limb),+, 0, 0, 0, 0]
|
||||
};
|
||||
}
|
||||
|
||||
pub static COMMON_OPS: CommonOps = CommonOps {
|
||||
num_limbs: 256 / LIMB_BITS,
|
||||
|
||||
q: Modulus {
|
||||
p: p256_limbs![
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
|
||||
0xffffffff
|
||||
],
|
||||
rr: p256_limbs![
|
||||
0x00000003, 0x00000000, 0xffffffff, 0xfffffffb, 0xfffffffe, 0xffffffff, 0xfffffffd,
|
||||
0x00000004
|
||||
],
|
||||
},
|
||||
|
||||
n: Elem {
|
||||
limbs: p256_limbs![
|
||||
0xfc632551, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, 0xffffffff, 0xffffffff, 0x00000000,
|
||||
0xffffffff
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // Unencoded
|
||||
},
|
||||
|
||||
a: Elem {
|
||||
limbs: p256_limbs![
|
||||
0xfffffffc, 0xffffffff, 0xffffffff, 0x00000003, 0x00000000, 0x00000000, 0x00000004,
|
||||
0xfffffffc
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // R
|
||||
},
|
||||
b: Elem {
|
||||
limbs: p256_limbs![
|
||||
0x29c4bddf, 0xd89cdf62, 0x78843090, 0xacf005cd, 0xf7212ed6, 0xe5a220ab, 0x04874834,
|
||||
0xdc30061d
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // R
|
||||
},
|
||||
|
||||
elem_add_impl: GFp_nistz256_add,
|
||||
elem_mul_mont: GFp_nistz256_mul_mont,
|
||||
elem_sqr_mont: GFp_nistz256_sqr_mont,
|
||||
|
||||
point_add_jacobian_impl: GFp_nistz256_point_add,
|
||||
};
|
||||
|
||||
pub static PRIVATE_KEY_OPS: PrivateKeyOps = PrivateKeyOps {
|
||||
common: &COMMON_OPS,
|
||||
elem_inv_squared: p256_elem_inv_squared,
|
||||
point_mul_base_impl: p256_point_mul_base_impl,
|
||||
point_mul_impl: GFp_nistz256_point_mul,
|
||||
};
|
||||
|
||||
fn p256_elem_inv_squared(a: &Elem<R>) -> Elem<R> {
|
||||
// Calculate a**-2 (mod q) == a**(q - 3) (mod q)
|
||||
//
|
||||
// The exponent (q - 3) is:
|
||||
//
|
||||
// 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc
|
||||
|
||||
#[inline]
|
||||
fn sqr_mul(a: &Elem<R>, squarings: usize, b: &Elem<R>) -> Elem<R> {
|
||||
elem_sqr_mul(&COMMON_OPS, a, squarings, b)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sqr_mul_acc(a: &mut Elem<R>, squarings: usize, b: &Elem<R>) {
|
||||
elem_sqr_mul_acc(&COMMON_OPS, a, squarings, b)
|
||||
}
|
||||
|
||||
let b_1 = &a;
|
||||
let b_11 = sqr_mul(b_1, 1, b_1);
|
||||
let b_111 = sqr_mul(&b_11, 1, b_1);
|
||||
let f_11 = sqr_mul(&b_111, 3, &b_111);
|
||||
let fff = sqr_mul(&f_11, 6, &f_11);
|
||||
let fff_111 = sqr_mul(&fff, 3, &b_111);
|
||||
let fffffff_11 = sqr_mul(&fff_111, 15, &fff_111);
|
||||
let ffffffff = sqr_mul(&fffffff_11, 2, &b_11);
|
||||
|
||||
// ffffffff00000001
|
||||
let mut acc = sqr_mul(&ffffffff, 31 + 1, b_1);
|
||||
|
||||
// ffffffff00000001000000000000000000000000ffffffff
|
||||
sqr_mul_acc(&mut acc, 96 + 32, &ffffffff);
|
||||
|
||||
// ffffffff00000001000000000000000000000000ffffffffffffffff
|
||||
sqr_mul_acc(&mut acc, 32, &ffffffff);
|
||||
|
||||
// ffffffff00000001000000000000000000000000fffffffffffffffffffffff_11
|
||||
sqr_mul_acc(&mut acc, 30, &fffffff_11);
|
||||
|
||||
// ffffffff00000001000000000000000000000000fffffffffffffffffffffffc
|
||||
COMMON_OPS.elem_square(&mut acc);
|
||||
COMMON_OPS.elem_square(&mut acc);
|
||||
|
||||
acc
|
||||
}
|
||||
|
||||
fn p256_point_mul_base_impl(g_scalar: &Scalar) -> Point {
|
||||
let mut r = Point::new_at_infinity();
|
||||
|
||||
// Keep this in sync with the logic for defining `GFp_USE_LARGE_TABLE` and
|
||||
// with the logic for deciding whether to test `GFp_nistz256_point_add_affine`
|
||||
// in suite_b/ops.rs.
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64"))]
|
||||
{
|
||||
extern "C" {
|
||||
fn GFp_nistz256_point_mul_base(
|
||||
r: *mut Limb, // [3][COMMON_OPS.num_limbs]
|
||||
g_scalar: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
}
|
||||
unsafe {
|
||||
GFp_nistz256_point_mul_base(r.xyz.as_mut_ptr(), g_scalar.limbs.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))]
|
||||
{
|
||||
static GENERATOR: (Elem<R>, Elem<R>) = (
|
||||
Elem {
|
||||
limbs: p256_limbs![
|
||||
0x18a9143c, 0x79e730d4, 0x5fedb601, 0x75ba95fc, 0x77622510, 0x79fb732b,
|
||||
0xa53755c6, 0x18905f76
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
},
|
||||
Elem {
|
||||
limbs: p256_limbs![
|
||||
0xce95560a, 0xddf25357, 0xba19e45c, 0x8b4ab8e4, 0xdd21f325, 0xd2e88688,
|
||||
0x25885d85, 0x8571ff18
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
},
|
||||
);
|
||||
|
||||
unsafe {
|
||||
GFp_nistz256_point_mul(
|
||||
r.xyz.as_mut_ptr(),
|
||||
g_scalar.limbs.as_ptr(),
|
||||
GENERATOR.0.limbs.as_ptr(),
|
||||
GENERATOR.1.limbs.as_ptr(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
pub static PUBLIC_KEY_OPS: PublicKeyOps = PublicKeyOps {
|
||||
common: &COMMON_OPS,
|
||||
};
|
||||
|
||||
pub static SCALAR_OPS: ScalarOps = ScalarOps {
|
||||
common: &COMMON_OPS,
|
||||
scalar_inv_to_mont_impl: p256_scalar_inv_to_mont,
|
||||
scalar_mul_mont: GFp_p256_scalar_mul_mont,
|
||||
};
|
||||
|
||||
pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
|
||||
scalar_ops: &SCALAR_OPS,
|
||||
public_key_ops: &PUBLIC_KEY_OPS,
|
||||
private_key_ops: &PRIVATE_KEY_OPS,
|
||||
|
||||
q_minus_n: Elem {
|
||||
limbs: p256_limbs![0x039cdaae, 0x0c46353d, 0x58e8617b, 0x43190553, 0, 0, 0, 0],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // Unencoded
|
||||
},
|
||||
};
|
||||
|
||||
pub static PRIVATE_SCALAR_OPS: PrivateScalarOps = PrivateScalarOps {
|
||||
scalar_ops: &SCALAR_OPS,
|
||||
|
||||
oneRR_mod_n: Scalar {
|
||||
limbs: p256_limbs![
|
||||
0xbe79eea2, 0x83244c95, 0x49bd6fa6, 0x4699799c, 0x2b6bec59, 0x2845b239, 0xf3d95620,
|
||||
0x66e12d94
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // R
|
||||
},
|
||||
};
|
||||
|
||||
fn p256_scalar_inv_to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
|
||||
// Calculate the modular inverse of scalar |a| using Fermat's Little
|
||||
// Theorem:
|
||||
//
|
||||
// a**-1 (mod n) == a**(n - 2) (mod n)
|
||||
//
|
||||
// The exponent (n - 2) is:
|
||||
//
|
||||
// 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f
|
||||
|
||||
#[inline]
|
||||
fn mul(a: &Scalar<R>, b: &Scalar<R>) -> Scalar<R> {
|
||||
binary_op(GFp_p256_scalar_mul_mont, a, b)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sqr(a: &Scalar<R>) -> Scalar<R> {
|
||||
unary_op(GFp_p256_scalar_sqr_mont, a)
|
||||
}
|
||||
|
||||
// Returns (`a` squared `squarings` times) * `b`.
|
||||
fn sqr_mul(a: &Scalar<R>, squarings: Limb, b: &Scalar<R>) -> Scalar<R> {
|
||||
debug_assert!(squarings >= 1);
|
||||
let mut tmp = Scalar::zero();
|
||||
unsafe { GFp_p256_scalar_sqr_rep_mont(tmp.limbs.as_mut_ptr(), a.limbs.as_ptr(), squarings) }
|
||||
mul(&tmp, b)
|
||||
}
|
||||
|
||||
// Sets `acc` = (`acc` squared `squarings` times) * `b`.
|
||||
fn sqr_mul_acc(acc: &mut Scalar<R>, squarings: Limb, b: &Scalar<R>) {
|
||||
debug_assert!(squarings >= 1);
|
||||
unsafe {
|
||||
GFp_p256_scalar_sqr_rep_mont(acc.limbs.as_mut_ptr(), acc.limbs.as_ptr(), squarings)
|
||||
}
|
||||
binary_op_assign(GFp_p256_scalar_mul_mont, acc, b);
|
||||
}
|
||||
|
||||
fn to_mont(a: &Scalar) -> Scalar<R> {
|
||||
static N_RR: Scalar<Unencoded> = Scalar {
|
||||
limbs: p256_limbs![
|
||||
0xbe79eea2, 0x83244c95, 0x49bd6fa6, 0x4699799c, 0x2b6bec59, 0x2845b239, 0xf3d95620,
|
||||
0x66e12d94
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
};
|
||||
binary_op(GFp_p256_scalar_mul_mont, a, &N_RR)
|
||||
}
|
||||
|
||||
// Indexes into `d`.
|
||||
const B_1: usize = 0;
|
||||
const B_10: usize = 1;
|
||||
const B_11: usize = 2;
|
||||
const B_101: usize = 3;
|
||||
const B_111: usize = 4;
|
||||
const B_1111: usize = 5;
|
||||
const B_10101: usize = 6;
|
||||
const B_101111: usize = 7;
|
||||
const DIGIT_COUNT: usize = 8;
|
||||
|
||||
let mut d = [Scalar::zero(); DIGIT_COUNT];
|
||||
|
||||
d[B_1] = to_mont(a);
|
||||
d[B_10] = sqr(&d[B_1]);
|
||||
d[B_11] = mul(&d[B_10], &d[B_1]);
|
||||
d[B_101] = mul(&d[B_10], &d[B_11]);
|
||||
d[B_111] = mul(&d[B_101], &d[B_10]);
|
||||
let b_1010 = sqr(&d[B_101]);
|
||||
d[B_1111] = mul(&b_1010, &d[B_101]);
|
||||
d[B_10101] = sqr_mul(&b_1010, 0 + 1, &d[B_1]);
|
||||
let b_101010 = sqr(&d[B_10101]);
|
||||
d[B_101111] = mul(&b_101010, &d[B_101]);
|
||||
let b_111111 = mul(&b_101010, &d[B_10101]);
|
||||
|
||||
let ff = sqr_mul(&b_111111, 0 + 2, &d[B_11]);
|
||||
let ffff = sqr_mul(&ff, 0 + 8, &ff);
|
||||
let ffffffff = sqr_mul(&ffff, 0 + 16, &ffff);
|
||||
|
||||
// ffffffff00000000ffffffff
|
||||
let mut acc = sqr_mul(&ffffffff, 32 + 32, &ffffffff);
|
||||
|
||||
// ffffffff00000000ffffffffffffffff
|
||||
sqr_mul_acc(&mut acc, 0 + 32, &ffffffff);
|
||||
|
||||
// The rest of the exponent, in binary, is:
|
||||
//
|
||||
// 1011110011100110111110101010110110100111000101111001111010000100
|
||||
// 1111001110111001110010101100001011111100011000110010010101001111
|
||||
|
||||
static REMAINING_WINDOWS: [(u8, u8); 26] = [
|
||||
(6, B_101111 as u8),
|
||||
(2 + 3, B_111 as u8),
|
||||
(2 + 2, B_11 as u8),
|
||||
(1 + 4, B_1111 as u8),
|
||||
(5, B_10101 as u8),
|
||||
(1 + 3, B_101 as u8),
|
||||
(3, B_101 as u8),
|
||||
(3, B_101 as u8),
|
||||
(2 + 3, B_111 as u8),
|
||||
(3 + 6, B_101111 as u8),
|
||||
(2 + 4, B_1111 as u8),
|
||||
(1 + 1, B_1 as u8),
|
||||
(4 + 1, B_1 as u8),
|
||||
(2 + 4, B_1111 as u8),
|
||||
(2 + 3, B_111 as u8),
|
||||
(1 + 3, B_111 as u8),
|
||||
(2 + 3, B_111 as u8),
|
||||
(2 + 3, B_101 as u8),
|
||||
(1 + 2, B_11 as u8),
|
||||
(4 + 6, B_101111 as u8),
|
||||
(2, B_11 as u8),
|
||||
(3 + 2, B_11 as u8),
|
||||
(3 + 2, B_11 as u8),
|
||||
(2 + 1, B_1 as u8),
|
||||
(2 + 5, B_10101 as u8),
|
||||
(2 + 4, B_1111 as u8),
|
||||
];
|
||||
|
||||
for &(squarings, digit) in &REMAINING_WINDOWS {
|
||||
sqr_mul_acc(&mut acc, Limb::from(squarings), &d[usize::from(digit)]);
|
||||
}
|
||||
|
||||
acc
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn GFp_nistz256_add(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
b: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
fn GFp_nistz256_mul_mont(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
b: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
fn GFp_nistz256_sqr_mont(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
|
||||
fn GFp_nistz256_point_add(
|
||||
r: *mut Limb, // [3][COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [3][COMMON_OPS.num_limbs]
|
||||
b: *const Limb, // [3][COMMON_OPS.num_limbs]
|
||||
);
|
||||
fn GFp_nistz256_point_mul(
|
||||
r: *mut Limb, // [3][COMMON_OPS.num_limbs]
|
||||
p_scalar: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
p_x: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
p_y: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
|
||||
fn GFp_p256_scalar_mul_mont(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
b: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
fn GFp_p256_scalar_sqr_mont(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
fn GFp_p256_scalar_sqr_rep_mont(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
rep: Limb,
|
||||
);
|
||||
}
|
||||
32
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_elem_mul_tests.txt
vendored
Normal file
32
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_elem_mul_tests.txt
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
a = 00
|
||||
b = 00
|
||||
r = 00
|
||||
|
||||
a = 00
|
||||
b = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe
|
||||
r = 00
|
||||
|
||||
a = 01
|
||||
b = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe
|
||||
r = fffffffd00000002fffffffdffffffff00000001fffffffcffffffff
|
||||
|
||||
a = 02
|
||||
b = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe
|
||||
r = 01fffffffa00000005fffffffbfffffffe00000003fffffff9fffffffe
|
||||
|
||||
a = 03
|
||||
b = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe
|
||||
r = 02fffffff700000008fffffff9fffffffd00000005fffffff6fffffffd
|
||||
|
||||
a = 7fffffff800000008000000000000000000000007fffffffffffffffffffffff
|
||||
b = 02
|
||||
r = fffffffd00000002fffffffdffffffff00000001fffffffcffffffff
|
||||
|
||||
a = 7fffffff80000000800000000000000000000000800000000000000000000000
|
||||
b = 02
|
||||
r = fffffffe00000003fffffffd0000000200000001fffffffe0000000300000000
|
||||
|
||||
a = 8000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 02
|
||||
r = 01
|
||||
24
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_elem_neg_tests.txt
vendored
Normal file
24
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_elem_neg_tests.txt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
a = 00
|
||||
b = 00
|
||||
|
||||
a = 01
|
||||
b = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe
|
||||
|
||||
a = 02
|
||||
b = ffffffff00000001000000000000000000000000fffffffffffffffffffffffd
|
||||
|
||||
a = 03
|
||||
b = ffffffff00000001000000000000000000000000fffffffffffffffffffffffc
|
||||
|
||||
a = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe
|
||||
b = 01
|
||||
|
||||
a = 7fffffff800000008000000000000000000000007fffffffffffffffffffffff
|
||||
b = 7fffffff80000000800000000000000000000000800000000000000000000000
|
||||
|
||||
a = 7fffffff80000000800000000000000000000000800000000000000000000000
|
||||
b = 7fffffff800000008000000000000000000000007fffffffffffffffffffffff
|
||||
|
||||
a = 8000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 7fffffff00000001000000000000000000000000ffffffffffffffffffffffff
|
||||
1048
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_elem_sum_tests.txt
vendored
Normal file
1048
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_elem_sum_tests.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
20
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_double_tests.txt
vendored
Normal file
20
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_double_tests.txt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
# G doubled once.
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = f6bb32e43dcf3a3b732205038d1490d9aa6ae3c1a433827d850046d410ddd64d, 78c577510a5b8a3b19a8fb0e92042dbe152cd7cbeb236ff82f3648d361bee1a5
|
||||
|
||||
# Point at infinity doubled. This uses the (0, 0, 0) representation of
|
||||
# the point at infinity instead of the classic (1, 1, 0)
|
||||
# representation.
|
||||
a = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# Point at infinity doubled. This form is the result of multiplying
|
||||
# n * G (affine), which is more interesting than the above case
|
||||
# because only the Z coordinate is zero.
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# (n - 1) * G doubled.
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = f6bb32e43dcf3a3b732205038d1490d9aa6ae3c1a433827d850046d410ddd64d, 873a88adf5a475c5e65704f16dfbd241ead3283514dc9007d0c9b72c9e411e5a
|
||||
1280
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_mul_base_tests.txt
vendored
Normal file
1280
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_mul_base_tests.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
13
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_mul_serialized_tests.txt
vendored
Normal file
13
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_mul_serialized_tests.txt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Similar to p256_point_mul_tests.txt, but tests point decoding and point
|
||||
# encoding too. In particular, the inputs coordinates here are not Montgomery
|
||||
# encoded, but the inputs in p256_point_mul_tests.txt are.
|
||||
|
||||
# Regression Test from https://github.com/golang/go/issues/20040
|
||||
|
||||
p_scalar = 2a265f8bcbdcaf94d58519141e578124cb40d64a501fba9c11847b28965bc737
|
||||
p = 04023819813ac969847059028ea88a1f30dfbcde03fc791d3a252c6b41211882eaf93e4ae433cc12cf2a43fc0ef26400c0e125508224cdb649380f25479148a4ad
|
||||
r = 044d4de80f1534850d261075997e3049321a0864082d24a917863366c0724f5ae3a22d2b7f7818a3563e0f7a76c9bf0921ac55e06e2e4d11795b233824b1db8cc0
|
||||
|
||||
p_scalar = 313f72ff9fe811bf573176231b286a3bdb6f1b14e05c40146590727a71c3bccd
|
||||
p = 04cc11887b2d66cbae8f4d306627192522932146b42f01d3c6f92bd5c8ba739b06a2f08a029cd06b46183085bae9248b0ed15b70280c7ef13a457f5af382426031
|
||||
r = 04831c3f6b5f762d2f461901577af41354ac5f228c2591f84f8a6e51e2e3f1799193f90934cd0ef2c698cc471c60a93524e87ab31ca2412252337f364513e43684
|
||||
1665
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_mul_tests.txt
vendored
Normal file
1665
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_mul_tests.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
80
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_sum_mixed_tests.txt
vendored
Normal file
80
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_sum_mixed_tests.txt
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
|
||||
# inf + inf == 2 * inf == inf
|
||||
a = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# inf (n*G) + inf (n*G) == 2 * inf == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# inf (n*G) + inf == 2 * inf == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# inf + inf (n*G) == 2 * inf == inf
|
||||
a = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# G + inf == G
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
|
||||
# G + inf (n*G) == G
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
|
||||
# inf + G == G
|
||||
a = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
r = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
|
||||
# inf (n*G) + G == G
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
r = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
|
||||
# G + (n-1)*G == inf; note that -G is (n-1)*G
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5
|
||||
r = inf
|
||||
|
||||
# (n-1)*G + -(n-1)*G == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
r = inf
|
||||
|
||||
# -(n-1)*G + (n-1)*G == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 92ccc25ad1cf08ffedba49d7efea212eb1f0eff79718a75e493c3f7c503eb15f, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5
|
||||
r = inf
|
||||
|
||||
# -(n-1)*G (affine) + (n-1)*G == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 92ccc25ad1cf08ffedba49d7efea212eb1f0eff79718a75e493c3f7c503eb15f, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5
|
||||
r = inf
|
||||
|
||||
# -(n-1)*G + -G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 92ccc25ad1cf08ffedba49d7efea212eb1f0eff79718a75e493c3f7c503eb15f, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5
|
||||
r = inf
|
||||
|
||||
# -G + -(n-1)*G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
r = inf
|
||||
|
||||
# -G + G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
r = inf
|
||||
|
||||
# G + -G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5
|
||||
r = inf
|
||||
120
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_sum_tests.txt
vendored
Normal file
120
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_point_sum_tests.txt
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
# inf + inf == 2 * inf == inf
|
||||
a = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# inf (n*G) + inf (n*G) == 2 * inf == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# inf (n*G) + inf == 2 * inf == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# inf + inf (n*G) == 2 * inf == inf
|
||||
a = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# G + inf == G
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
|
||||
# G + inf (n*G) == G
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
|
||||
# inf + G == G
|
||||
a = 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
|
||||
# inf (n*G) + G == G
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
|
||||
|
||||
# G + G == 2*G
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = f6bb32e43dcf3a3b732205038d1490d9aa6ae3c1a433827d850046d410ddd64d, 78c577510a5b8a3b19a8fb0e92042dbe152cd7cbeb236ff82f3648d361bee1a5
|
||||
|
||||
# (n-1)*G + G == inf; note that -G is (n-1)*G
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = inf
|
||||
|
||||
# G + (n-1)*G == inf; note that -G is (n-1)*G
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = inf
|
||||
|
||||
# (n-1)*G + (n-1)*G == 2*(n-1)*G
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = f6bb32e43dcf3a3b732205038d1490d9aa6ae3c1a433827d850046d410ddd64d, 873a88adf5a475c5e65704f16dfbd241ead3283514dc9007d0c9b72c9e411e5a
|
||||
|
||||
# (n-1)*G (affine) + (n-1)*G == 2*(n-1)*G
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = f6bb32e43dcf3a3b732205038d1490d9aa6ae3c1a433827d850046d410ddd64d, 873a88adf5a475c5e65704f16dfbd241ead3283514dc9007d0c9b72c9e411e5a
|
||||
|
||||
# (n-1)*G + -(n-1)*G == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 92ccc25ad1cf08ffedba49d7efea212eb1f0eff79718a75e493c3f7c503eb15f, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = inf
|
||||
|
||||
# -(n-1)*G + (n-1)*G == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 92ccc25ad1cf08ffedba49d7efea212eb1f0eff79718a75e493c3f7c503eb15f, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = inf
|
||||
|
||||
# -(n-1)*G (affine) + (n-1)*G == inf
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 92ccc25ad1cf08ffedba49d7efea212eb1f0eff79718a75e493c3f7c503eb15f, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = inf
|
||||
|
||||
# -(n-1)*G + -G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 92ccc25ad1cf08ffedba49d7efea212eb1f0eff79718a75e493c3f7c503eb15f, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = inf
|
||||
|
||||
# -G + -(n-1)*G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 92ccc25ad1cf08ffedba49d7efea212eb1f0eff79718a75e493c3f7c503eb15f, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = inf
|
||||
|
||||
# (n-1)*G + -G; == -2*G; note that -G == (n-1)*G (affine)
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = f6bb32e43dcf3a3b732205038d1490d9aa6ae3c1a433827d850046d410ddd64d, 873a88adf5a475c5e65704f16dfbd241ead3283514dc9007d0c9b72c9e411e5a
|
||||
|
||||
# -G + (n-1)*G == -2*G; note that -G is (n-1)*G (affine)
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = f6bb32e43dcf3a3b732205038d1490d9aa6ae3c1a433827d850046d410ddd64d, 873a88adf5a475c5e65704f16dfbd241ead3283514dc9007d0c9b72c9e411e5a
|
||||
|
||||
# (n-1)*G + -G == -2*G; note that -G is (n-1)*G (affine)
|
||||
a = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = f6bb32e43dcf3a3b732205038d1490d9aa6ae3c1a433827d850046d410ddd64d, 873a88adf5a475c5e65704f16dfbd241ead3283514dc9007d0c9b72c9e411e5a
|
||||
|
||||
# -G + (n-1)*G == -2*G; note that -G = (n-1)*G
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 2b11cb945c8cf152ffa4c9c2b1c965b019b35d0b7626919ef0ae6cb9d232f8af, 6d333da42e30f7011245b6281015ded14e0f100968e758a1b6c3c083afc14ea0, 3c396f06c1dc69e4f4b2dce51cd660f761064a4ab098ef61ba3868961f0ef178
|
||||
r = f6bb32e43dcf3a3b732205038d1490d9aa6ae3c1a433827d850046d410ddd64d, 873a88adf5a475c5e65704f16dfbd241ead3283514dc9007d0c9b72c9e411e5a
|
||||
|
||||
# -G + G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = inf
|
||||
|
||||
# G + -G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
b = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c, 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5, 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
|
||||
r = inf
|
||||
86
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_scalar_mul_tests.txt
vendored
Normal file
86
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_scalar_mul_tests.txt
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
a = 00
|
||||
b = 00
|
||||
r = 00
|
||||
|
||||
a = 00
|
||||
b = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
|
||||
r = 00
|
||||
|
||||
a = 01
|
||||
b = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
|
||||
r = 9f2f99cbb6fa3e17f80749fbe19f88da020806cb63c12ed5259e01cb6049a8d8
|
||||
|
||||
a = 02
|
||||
b = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
|
||||
r = 3e5f33986df47c2ef00e93f7c33f11b4472912e9206abf25578238d3c4302c5f
|
||||
|
||||
a = 03
|
||||
b = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
|
||||
r = dd8ecd6424eeba46e815ddf3a4de9a8e493119b4842bedfa7d203a9f2479d537
|
||||
|
||||
a = 7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8
|
||||
b = 02
|
||||
r = 9f2f99cbb6fa3e17f80749fbe19f88da020806cb63c12ed5259e01cb6049a8d8
|
||||
|
||||
a = 7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a9
|
||||
b = 02
|
||||
r = 60d066334905c1e907f8b6041e607725badef3e243566fafce1bc8f79c197c79
|
||||
|
||||
a = 8000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 02
|
||||
r = 01
|
||||
|
||||
# From BoringSSL
|
||||
|
||||
a = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
b = b4e9b0aea84aa5ed86964a22881a4d0e58f88e9225f30990c18751e7d4b9ec95
|
||||
r = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
a = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf
|
||||
b = 5d24e62244973fbd829573d5a579b4e89a6512933a2c3d255bbdbc1c89028323
|
||||
r = 5d24e62244973fbd829573d5a579b4e89a6512933a2c3d255bbdbc1c89028323
|
||||
|
||||
a = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
|
||||
b = abafdc695e4c2c850f8fc60f1efdbf7406a3cd2c6c59bb7e608985723896c187
|
||||
r = 917b1214c7b31a7ee7e53be0b41a139e435ff576b51ec6af1e1a944412bea38b
|
||||
|
||||
a = cf0f01b83670a1c79154ea16f3574ca2d4c688a3c3b6017795cbe54854418904
|
||||
b = c5ec4d3b00fb2e11fb3b1aa09e60f7d187f7c515977d1343dab9745961fcbb43
|
||||
r = 7aaddcee32e3b340af5ad06f854284cbbce5a1ab919e9b7771c3b0e937093438
|
||||
|
||||
a = 50023f9913879ac4020bc45a89a0ea89082db6265b96b851af29969dd8a9661c
|
||||
b = 7c165b1cba80808db114441563aa0fbfba41b9e8acff77312a2dd2138b74ef89
|
||||
r = 3d2ca1705d8d38cbc76a5409c6535044733cafcb95d12654af1d14de177978b5
|
||||
|
||||
a = 4d5341ea735e53d2e4f2934755642adee209bd0e5a1506206513227f3c48b270
|
||||
b = 6e48f2b60eb8fb86760134abaf3d61692557862924069c599ceb31309ea18704
|
||||
r = 37cde3e35c814d4287bd345b910d687983929907b7a08afa2acd8596832ea86c
|
||||
|
||||
a = 33d06c3f5a595a41a6f9c4356f8ab2b8c550d4c64b806eab5560af247c5fa9ed
|
||||
b = 0e52f34adf5754343bcf3529d652620da3c05b5dd9cdcddfb08b674a1ad21a09
|
||||
r = 9dc64d7b4c1bc33b930e0daee2a24fc41f770378659ee71b846d2239b0fea8ea
|
||||
|
||||
a = 8f211780cce4f93b7193b9378e6f83e1147fb3602b052eef782de8cc833e54ab
|
||||
b = e1e4f7f1feb15be64292cff86b47cd9730bcb15b133340022b824d591a660cdf
|
||||
r = dfa2b683b1ae23027c7c109e0abb40a1366eda027ad2cad1a09061a57bee391f
|
||||
|
||||
a = 803c279c7e4c11a5568290c0a5789ceab6860f51a942bf646501a45e1ec0a6bf
|
||||
b = c0a1145a12037129c571f5f939bf16ea0b8b480f08ec774c045d059841f7d5ed
|
||||
r = ab48fa3b4aa692a7c077cc55ee3c3fff895118a23728c2fa5f361b30730d955a
|
||||
|
||||
a = 0e5c95158297d75dbf0b02c3090730f65bf14704495b14837dd907af569407f1
|
||||
b = 5a03e3787c8772b2fb7ab07d7fe7fe653a58bdae7fde3174c6ed305e524f5728
|
||||
r = 71296d305dcf9ce39010ea4f4bbf9f7c1064a413597bdc7574c13dea3fa514dc
|
||||
|
||||
a = 366299be07886f7846fc74231db624b169360e3c8f60196a1afc9f2101e03922
|
||||
b = d6d7c830a6edb6861868b964519a6b68f6f24f7c09d66003f3f88eadd1e00158
|
||||
r = 0b89596bf5054ebe95a39dab6e975b58190160610b09b2a4f93331ecc0e79fd3
|
||||
|
||||
a = 8f36f0ef275a72192c3b7388e84df2b8acf66fc53aaf556e3be05c76b3f782c0
|
||||
b = 704e519363d44e8df8d91f5f347eb61e8d3e85c8fc1b82980c370a379b2bc81c
|
||||
r = b70a392e3ce5e85b5efbbded9b8c16a3068ba9b93b4cbed9a9a71dffaad6b58a
|
||||
|
||||
a = bf4466ef4dea9f06f0f3b4f14e01140a774262c7e0706584f4d7dac19be46d58
|
||||
b = 4af12d528b2cef0f6714961bca2ab682f8abaa97600ea8181f71563d56f8a9f5
|
||||
r = 7b6827c0881b9846e32499e13277efb07917cf4b8c8c72bfb3daa8c1786a8e15
|
||||
65
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_scalar_square_tests.txt
vendored
Normal file
65
zeroidc/vendor/ring/src/ec/suite_b/ops/p256_scalar_square_tests.txt
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
a = 00
|
||||
r = 00
|
||||
|
||||
a = 00
|
||||
r = 00
|
||||
|
||||
a = 01
|
||||
r = 60d066334905c1e907f8b6041e607725badef3e243566fafce1bc8f79c197c79
|
||||
|
||||
a = 02
|
||||
r = 834198ce241707a31fe2d8107981dc972e94d4db6642203a44b5591b7402cc93
|
||||
|
||||
a = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
|
||||
r = 60d066334905c1e907f8b6041e607725badef3e243566fafce1bc8f79c197c79
|
||||
|
||||
a = ffffffff80000000600000002fffffff
|
||||
r = 965f4779ac1ddbac28a14bd1e0c28dcb091d48820b4116d22afbc3f00f90f476
|
||||
|
||||
a = ffffffff800000006000000030000000
|
||||
r = 9e07cb5cdf45939f41541805d2c24625e1cb1719e37a89efc755b5e58e585515
|
||||
|
||||
a = 8000000000000000000000000000000000000000000000000000000000000000
|
||||
r = 4000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
# From BoringSSL
|
||||
|
||||
a = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
r = 0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
a = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf
|
||||
r = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf
|
||||
|
||||
a = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
|
||||
r = 60d066334905c1e907f8b6041e607725badef3e243566fafce1bc8f79c197c79
|
||||
|
||||
a = da43b8dd7fe8830a4fe8980ec585ccbe903a2965a695cdff398200b74b2ede41
|
||||
r = 5ec68604412205b380e26ee4e4081eccc10ac7d1417b09cd534f8517b0de81ec
|
||||
|
||||
a = a82a2b8bdbf8a37dc7cb5799691494a8c9fbf649686a4d250dc30697feb0fa47
|
||||
r = 552c094a8841621d6cc26b3b54ce5da5664283888445196a6433d3cfdcad3aee
|
||||
|
||||
a = d785006e250410d9dcc6d7740795a7374c25b00b9c9a37b8285694a07307eacd
|
||||
r = 971aaa9e70ad082cf43725f2e65bc73f4bf762459cee13167545072ec7bdcaf8
|
||||
|
||||
a = 69d6d9f5417e87d603a3fb6acafa0d1f974abf94ca57ce58d718a0ad5d02a496
|
||||
r = eb3284e5799fbe93171f08e6de9f792cd17f036b3a17671b0310e49b48e589b3
|
||||
|
||||
a = 1c28f742c3e26e74901d0425f2eb4d5272524668d2405875b32cf6433f212900
|
||||
r = 74f70a95399b7ad061a2200fa50528d68eee4654341c8158101e1e3f8f16e642
|
||||
|
||||
a = 026b2f69f0259d221920b2f358b378a79826f0332ee36afa257765043e3d6732
|
||||
r = e1e9cfa4724995bb50971ca22f3c028cd31cb51fbef8a37c31f10fd1d468f13b
|
||||
|
||||
a = 376ed4fadcc1c6c4160a0c9c2ab7c62260367968b08d304d47c65f25625d7d60
|
||||
r = b9ccb67f377e1278f1d2eeda26e5eed76f32406c9deed9764fc0aa346d91e02b
|
||||
|
||||
a = 50f66867d0a4ef389678d760d2a4db886583b4c068d0e240f7ddf3472c871304
|
||||
r = 82c3467bc5f7ca8b45f4ee61546745e2f53755a02e87f65f572418d60e471c8b
|
||||
|
||||
a = 5b8bd82b37206d2b727f19ad2d02f63773470074dde7d43d2a77c448ddf2f978
|
||||
r = dbf3c2fc67a0688c3b5ff12cab1739d50b6093c5d98943d388652b1207e4a0f2
|
||||
|
||||
a = bed7b3a4dada0e16984eb59ee239005ab212e5b1772cdd5d240c8ee268f65c81
|
||||
r = 9232aa2759ca9c5efbaefb0cf45cc6bc9c89def8c25e5c169fe623f30787df36
|
||||
370
zeroidc/vendor/ring/src/ec/suite_b/ops/p384.rs
vendored
Normal file
370
zeroidc/vendor/ring/src/ec/suite_b/ops/p384.rs
vendored
Normal file
@@ -0,0 +1,370 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::{
|
||||
elem::{binary_op, binary_op_assign},
|
||||
elem_sqr_mul, elem_sqr_mul_acc, Modulus, *,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
macro_rules! p384_limbs {
|
||||
[$($limb:expr),+] => {
|
||||
limbs![$($limb),+]
|
||||
};
|
||||
}
|
||||
|
||||
pub static COMMON_OPS: CommonOps = CommonOps {
|
||||
num_limbs: 384 / LIMB_BITS,
|
||||
|
||||
q: Modulus {
|
||||
p: p384_limbs![
|
||||
0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xfffffffe, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
|
||||
],
|
||||
rr: p384_limbs![1, 0xfffffffe, 0, 2, 0, 0xfffffffe, 0, 2, 1, 0, 0, 0],
|
||||
},
|
||||
n: Elem {
|
||||
limbs: p384_limbs![
|
||||
0xccc52973, 0xecec196a, 0x48b0a77a, 0x581a0db2, 0xf4372ddf, 0xc7634d81, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // Unencoded
|
||||
},
|
||||
|
||||
a: Elem {
|
||||
limbs: p384_limbs![
|
||||
0xfffffffc, 0x00000003, 0x00000000, 0xfffffffc, 0xfffffffb, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // Unreduced
|
||||
},
|
||||
b: Elem {
|
||||
limbs: p384_limbs![
|
||||
0x9d412dcc, 0x08118871, 0x7a4c32ec, 0xf729add8, 0x1920022e, 0x77f2209b, 0x94938ae2,
|
||||
0xe3374bee, 0x1f022094, 0xb62b21f4, 0x604fbff9, 0xcd08114b
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // Unreduced
|
||||
},
|
||||
|
||||
elem_add_impl: GFp_p384_elem_add,
|
||||
elem_mul_mont: GFp_p384_elem_mul_mont,
|
||||
elem_sqr_mont: GFp_p384_elem_sqr_mont,
|
||||
|
||||
point_add_jacobian_impl: GFp_nistz384_point_add,
|
||||
};
|
||||
|
||||
pub static PRIVATE_KEY_OPS: PrivateKeyOps = PrivateKeyOps {
|
||||
common: &COMMON_OPS,
|
||||
elem_inv_squared: p384_elem_inv_squared,
|
||||
point_mul_base_impl: p384_point_mul_base_impl,
|
||||
point_mul_impl: GFp_nistz384_point_mul,
|
||||
};
|
||||
|
||||
fn p384_elem_inv_squared(a: &Elem<R>) -> Elem<R> {
|
||||
// Calculate a**-2 (mod q) == a**(q - 3) (mod q)
|
||||
//
|
||||
// The exponent (q - 3) is:
|
||||
//
|
||||
// 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\
|
||||
// ffffffff0000000000000000fffffffc
|
||||
|
||||
#[inline]
|
||||
fn sqr_mul(a: &Elem<R>, squarings: usize, b: &Elem<R>) -> Elem<R> {
|
||||
elem_sqr_mul(&COMMON_OPS, a, squarings, b)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sqr_mul_acc(a: &mut Elem<R>, squarings: usize, b: &Elem<R>) {
|
||||
elem_sqr_mul_acc(&COMMON_OPS, a, squarings, b)
|
||||
}
|
||||
|
||||
let b_1 = &a;
|
||||
let b_11 = sqr_mul(b_1, 1, b_1);
|
||||
let b_111 = sqr_mul(&b_11, 1, b_1);
|
||||
let f_11 = sqr_mul(&b_111, 3, &b_111);
|
||||
let fff = sqr_mul(&f_11, 6, &f_11);
|
||||
let fff_111 = sqr_mul(&fff, 3, &b_111);
|
||||
let fffffff_11 = sqr_mul(&fff_111, 15, &fff_111);
|
||||
|
||||
let fffffffffffffff = sqr_mul(&fffffff_11, 30, &fffffff_11);
|
||||
|
||||
let ffffffffffffffffffffffffffffff = sqr_mul(&fffffffffffffff, 60, &fffffffffffffff);
|
||||
|
||||
// ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
let mut acc = sqr_mul(
|
||||
&ffffffffffffffffffffffffffffff,
|
||||
120,
|
||||
&ffffffffffffffffffffffffffffff,
|
||||
);
|
||||
|
||||
// fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_111
|
||||
sqr_mul_acc(&mut acc, 15, &fff_111);
|
||||
|
||||
// fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff
|
||||
sqr_mul_acc(&mut acc, 1 + 30, &fffffff_11);
|
||||
sqr_mul_acc(&mut acc, 2, &b_11);
|
||||
|
||||
// fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff
|
||||
// 0000000000000000fffffff_11
|
||||
sqr_mul_acc(&mut acc, 64 + 30, &fffffff_11);
|
||||
|
||||
// fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff
|
||||
// 0000000000000000fffffffc
|
||||
COMMON_OPS.elem_square(&mut acc);
|
||||
COMMON_OPS.elem_square(&mut acc);
|
||||
|
||||
acc
|
||||
}
|
||||
|
||||
fn p384_point_mul_base_impl(a: &Scalar) -> Point {
|
||||
// XXX: Not efficient. TODO: Precompute multiples of the generator.
|
||||
static GENERATOR: (Elem<R>, Elem<R>) = (
|
||||
Elem {
|
||||
limbs: p384_limbs![
|
||||
0x49c0b528, 0x3dd07566, 0xa0d6ce38, 0x20e378e2, 0x541b4d6e, 0x879c3afc, 0x59a30eff,
|
||||
0x64548684, 0x614ede2b, 0x812ff723, 0x299e1513, 0x4d3aadc2
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
},
|
||||
Elem {
|
||||
limbs: p384_limbs![
|
||||
0x4b03a4fe, 0x23043dad, 0x7bb4a9ac, 0xa1bfa8bf, 0x2e83b050, 0x8bade756, 0x68f4ffd9,
|
||||
0xc6c35219, 0x3969a840, 0xdd800226, 0x5a15c5e9, 0x2b78abc2
|
||||
],
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
},
|
||||
);
|
||||
|
||||
PRIVATE_KEY_OPS.point_mul(a, &GENERATOR)
|
||||
}
|
||||
|
||||
pub static PUBLIC_KEY_OPS: PublicKeyOps = PublicKeyOps {
|
||||
common: &COMMON_OPS,
|
||||
};
|
||||
|
||||
pub static SCALAR_OPS: ScalarOps = ScalarOps {
|
||||
common: &COMMON_OPS,
|
||||
scalar_inv_to_mont_impl: p384_scalar_inv_to_mont,
|
||||
scalar_mul_mont: GFp_p384_scalar_mul_mont,
|
||||
};
|
||||
|
||||
pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
|
||||
scalar_ops: &SCALAR_OPS,
|
||||
public_key_ops: &PUBLIC_KEY_OPS,
|
||||
private_key_ops: &PRIVATE_KEY_OPS,
|
||||
|
||||
q_minus_n: Elem {
|
||||
limbs: p384_limbs![
|
||||
0x333ad68c, 0x1313e696, 0xb74f5885, 0xa7e5f24c, 0x0bc8d21f, 0x389cb27e, 0, 0, 0, 0, 0,
|
||||
0
|
||||
],
|
||||
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // Unencoded
|
||||
},
|
||||
};
|
||||
|
||||
pub static PRIVATE_SCALAR_OPS: PrivateScalarOps = PrivateScalarOps {
|
||||
scalar_ops: &SCALAR_OPS,
|
||||
|
||||
oneRR_mod_n: Scalar {
|
||||
limbs: N_RR_LIMBS,
|
||||
m: PhantomData,
|
||||
encoding: PhantomData, // R
|
||||
},
|
||||
};
|
||||
|
||||
fn p384_scalar_inv_to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
|
||||
// Calculate the modular inverse of scalar |a| using Fermat's Little
|
||||
// Theorem:
|
||||
//
|
||||
// a**-1 (mod n) == a**(n - 2) (mod n)
|
||||
//
|
||||
// The exponent (n - 2) is:
|
||||
//
|
||||
// 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf\
|
||||
// 581a0db248b0a77aecec196accc52971.
|
||||
|
||||
fn mul(a: &Scalar<R>, b: &Scalar<R>) -> Scalar<R> {
|
||||
binary_op(GFp_p384_scalar_mul_mont, a, b)
|
||||
}
|
||||
|
||||
fn sqr(a: &Scalar<R>) -> Scalar<R> {
|
||||
binary_op(GFp_p384_scalar_mul_mont, a, a)
|
||||
}
|
||||
|
||||
fn sqr_mut(a: &mut Scalar<R>) {
|
||||
unary_op_from_binary_op_assign(GFp_p384_scalar_mul_mont, a);
|
||||
}
|
||||
|
||||
// Returns (`a` squared `squarings` times) * `b`.
|
||||
fn sqr_mul(a: &Scalar<R>, squarings: usize, b: &Scalar<R>) -> Scalar<R> {
|
||||
debug_assert!(squarings >= 1);
|
||||
let mut tmp = sqr(a);
|
||||
for _ in 1..squarings {
|
||||
sqr_mut(&mut tmp);
|
||||
}
|
||||
mul(&tmp, b)
|
||||
}
|
||||
|
||||
// Sets `acc` = (`acc` squared `squarings` times) * `b`.
|
||||
fn sqr_mul_acc(acc: &mut Scalar<R>, squarings: usize, b: &Scalar<R>) {
|
||||
debug_assert!(squarings >= 1);
|
||||
for _ in 0..squarings {
|
||||
sqr_mut(acc);
|
||||
}
|
||||
binary_op_assign(GFp_p384_scalar_mul_mont, acc, b)
|
||||
}
|
||||
|
||||
fn to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
|
||||
static N_RR: Scalar<Unencoded> = Scalar {
|
||||
limbs: N_RR_LIMBS,
|
||||
m: PhantomData,
|
||||
encoding: PhantomData,
|
||||
};
|
||||
binary_op(GFp_p384_scalar_mul_mont, a, &N_RR)
|
||||
}
|
||||
|
||||
// Indexes into `d`.
|
||||
const B_1: usize = 0;
|
||||
const B_11: usize = 1;
|
||||
const B_101: usize = 2;
|
||||
const B_111: usize = 3;
|
||||
const B_1001: usize = 4;
|
||||
const B_1011: usize = 5;
|
||||
const B_1101: usize = 6;
|
||||
const B_1111: usize = 7;
|
||||
const DIGIT_COUNT: usize = 8;
|
||||
|
||||
let mut d = [Scalar::zero(); DIGIT_COUNT];
|
||||
d[B_1] = to_mont(a);
|
||||
let b_10 = sqr(&d[B_1]);
|
||||
for i in B_11..DIGIT_COUNT {
|
||||
d[i] = mul(&d[i - 1], &b_10);
|
||||
}
|
||||
|
||||
let ff = sqr_mul(&d[B_1111], 0 + 4, &d[B_1111]);
|
||||
let ffff = sqr_mul(&ff, 0 + 8, &ff);
|
||||
let ffffffff = sqr_mul(&ffff, 0 + 16, &ffff);
|
||||
|
||||
let ffffffffffffffff = sqr_mul(&ffffffff, 0 + 32, &ffffffff);
|
||||
|
||||
let ffffffffffffffffffffffff = sqr_mul(&ffffffffffffffff, 0 + 32, &ffffffff);
|
||||
|
||||
// ffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
let mut acc = sqr_mul(&ffffffffffffffffffffffff, 0 + 96, &ffffffffffffffffffffffff);
|
||||
|
||||
// The rest of the exponent, in binary, is:
|
||||
//
|
||||
// 1100011101100011010011011000000111110100001101110010110111011111
|
||||
// 0101100000011010000011011011001001001000101100001010011101111010
|
||||
// 1110110011101100000110010110101011001100110001010010100101110001
|
||||
|
||||
static REMAINING_WINDOWS: [(u8, u8); 39] = [
|
||||
(2, B_11 as u8),
|
||||
(3 + 3, B_111 as u8),
|
||||
(1 + 2, B_11 as u8),
|
||||
(3 + 2, B_11 as u8),
|
||||
(1 + 4, B_1001 as u8),
|
||||
(4, B_1011 as u8),
|
||||
(6 + 4, B_1111 as u8),
|
||||
(3, B_101 as u8),
|
||||
(4 + 1, B_1 as u8),
|
||||
(4, B_1011 as u8),
|
||||
(4, B_1001 as u8),
|
||||
(1 + 4, B_1101 as u8),
|
||||
(4, B_1101 as u8),
|
||||
(4, B_1111 as u8),
|
||||
(1 + 4, B_1011 as u8),
|
||||
(6 + 4, B_1101 as u8),
|
||||
(5 + 4, B_1101 as u8),
|
||||
(4, B_1011 as u8),
|
||||
(2 + 4, B_1001 as u8),
|
||||
(2 + 1, B_1 as u8),
|
||||
(3 + 4, B_1011 as u8),
|
||||
(4 + 3, B_101 as u8),
|
||||
(2 + 3, B_111 as u8),
|
||||
(1 + 4, B_1111 as u8),
|
||||
(1 + 4, B_1011 as u8),
|
||||
(4, B_1011 as u8),
|
||||
(2 + 3, B_111 as u8),
|
||||
(1 + 2, B_11 as u8),
|
||||
(5 + 2, B_11 as u8),
|
||||
(2 + 4, B_1011 as u8),
|
||||
(1 + 3, B_101 as u8),
|
||||
(1 + 2, B_11 as u8),
|
||||
(2 + 2, B_11 as u8),
|
||||
(2 + 2, B_11 as u8),
|
||||
(3 + 3, B_101 as u8),
|
||||
(2 + 3, B_101 as u8),
|
||||
(2 + 3, B_101 as u8),
|
||||
(2, B_11 as u8),
|
||||
(3 + 1, B_1 as u8),
|
||||
];
|
||||
|
||||
for &(squarings, digit) in &REMAINING_WINDOWS[..] {
|
||||
sqr_mul_acc(&mut acc, usize::from(squarings), &d[usize::from(digit)]);
|
||||
}
|
||||
|
||||
acc
|
||||
}
|
||||
|
||||
unsafe extern "C" fn GFp_p384_elem_sqr_mont(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
) {
|
||||
// XXX: Inefficient. TODO: Make a dedicated squaring routine.
|
||||
GFp_p384_elem_mul_mont(r, a, a);
|
||||
}
|
||||
|
||||
const N_RR_LIMBS: [Limb; MAX_LIMBS] = p384_limbs![
|
||||
0x19b409a9, 0x2d319b24, 0xdf1aa419, 0xff3d81e5, 0xfcb82947, 0xbc3e483a, 0x4aab1cc5, 0xd40d4917,
|
||||
0x28266895, 0x3fb05b7a, 0x2b39bf21, 0x0c84ee01
|
||||
];
|
||||
|
||||
extern "C" {
|
||||
fn GFp_p384_elem_add(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
b: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
fn GFp_p384_elem_mul_mont(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
b: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
|
||||
fn GFp_nistz384_point_add(
|
||||
r: *mut Limb, // [3][COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [3][COMMON_OPS.num_limbs]
|
||||
b: *const Limb, // [3][COMMON_OPS.num_limbs]
|
||||
);
|
||||
fn GFp_nistz384_point_mul(
|
||||
r: *mut Limb, // [3][COMMON_OPS.num_limbs]
|
||||
p_scalar: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
p_x: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
p_y: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
|
||||
fn GFp_p384_scalar_mul_mont(
|
||||
r: *mut Limb, // [COMMON_OPS.num_limbs]
|
||||
a: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
b: *const Limb, // [COMMON_OPS.num_limbs]
|
||||
);
|
||||
}
|
||||
27
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_elem_div_by_2_tests.txt
vendored
Normal file
27
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_elem_div_by_2_tests.txt
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
a = 00
|
||||
r = 00
|
||||
|
||||
a = 00
|
||||
r = 00
|
||||
|
||||
a = 01
|
||||
r = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff800000000000000080000000
|
||||
|
||||
a = 02
|
||||
r = 01
|
||||
|
||||
a = 03
|
||||
r = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff800000000000000080000001
|
||||
|
||||
a = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe
|
||||
r = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff80000000000000007fffffff
|
||||
|
||||
a = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff80000000000000007fffffff
|
||||
r = bfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3fffffff4000000000000000bfffffff
|
||||
|
||||
a = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff800000000000000080000000
|
||||
r = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000
|
||||
|
||||
a = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
r = 400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
32
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_elem_mul_tests.txt
vendored
Normal file
32
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_elem_mul_tests.txt
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
a = 00
|
||||
b = 00
|
||||
r = 00
|
||||
|
||||
a = 00
|
||||
b = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe
|
||||
r = 00
|
||||
|
||||
a = 01
|
||||
b = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe
|
||||
r = ffffffebffffffebfffffff3fffffffd0000000300000005000000040000000100000013000000270000001ffffffff9
|
||||
|
||||
a = 02
|
||||
b = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe
|
||||
r = ffffffd7ffffffd7ffffffe7fffffffa000000060000000a0000000800000003000000270000004e0000003efffffff3
|
||||
|
||||
a = 03
|
||||
b = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe
|
||||
r = ffffffc3ffffffc3ffffffdbfffffff7000000090000000f0000000c000000050000003b000000750000005dffffffed
|
||||
|
||||
a = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff80000000000000007fffffff
|
||||
b = 02
|
||||
r = ffffffebffffffebfffffff3fffffffd0000000300000005000000040000000100000013000000270000001ffffffff9
|
||||
|
||||
a = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff800000000000000080000000
|
||||
b = 02
|
||||
r = 14000000140000000c00000002fffffffcfffffffafffffffbfffffffdffffffebffffffd8ffffffe100000006
|
||||
|
||||
a = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 02
|
||||
r = 01
|
||||
24
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_elem_neg_tests.txt
vendored
Normal file
24
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_elem_neg_tests.txt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
a = 00
|
||||
b = 00
|
||||
|
||||
a = 01
|
||||
b = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe
|
||||
|
||||
a = 02
|
||||
b = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd
|
||||
|
||||
a = 03
|
||||
b = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc
|
||||
|
||||
a = fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe
|
||||
b = 01
|
||||
|
||||
a = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff80000000000000007fffffff
|
||||
b = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff800000000000000080000000
|
||||
|
||||
a = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff800000000000000080000000
|
||||
b = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffff80000000000000007fffffff
|
||||
|
||||
a = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff
|
||||
1559
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_elem_sum_tests.txt
vendored
Normal file
1559
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_elem_sum_tests.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
20
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_point_double_tests.txt
vendored
Normal file
20
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_point_double_tests.txt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
# G doubled once.
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = db93b776427460c39c90a4fd2de4b506da821495f0687f503504e6f0ff9d48a18e6c8f2e022b53f0c8229e55783dde91, e34947f7123df0c2070d430900b0e68409f1fe415172bad915e4f18bdc588258e8e8e4a8c2aaccd842ea84633140bfda
|
||||
|
||||
# Point at infinity doubled. This uses the (0, 0, 0) representation of
|
||||
# the point at infinity instead of the classic (1, 1, 0)
|
||||
# representation.
|
||||
a = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# Point at infinity doubled. This form is the result of multiplying
|
||||
# n * G (affine), which is more interesting than the above case
|
||||
# because only the Z coordinate is zero.
|
||||
a = 4a0fd63f894499928e4b2b72aced45cfc589976f4ff86f78c904d59da9379a62b702d968c1184834c11db28c7356ceb6, be113b04484cd4bc215a9f2a33a674c3764c38ca4de135dd50ce8dcf3c85d55a5aad0e171860bdb6c58201e6212d9ac5, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# (n - 1) * G doubled.
|
||||
a = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = db93b776427460c39c90a4fd2de4b506da821495f0687f503504e6f0ff9d48a18e6c8f2e022b53f0c8229e55783dde91, 1cb6b808edc20f3df8f2bcf6ff4f197bf60e01beae8d4526ea1b0e7423a77da617171b563d553327bd157b9dcebf4025
|
||||
1280
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_point_mul_base_tests.txt
vendored
Normal file
1280
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_point_mul_base_tests.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1664
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_point_mul_tests.txt
vendored
Normal file
1664
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_point_mul_tests.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
120
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_point_sum_tests.txt
vendored
Normal file
120
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_point_sum_tests.txt
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
# inf + inf == 2 * inf == inf
|
||||
a = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# inf (n*G) + inf (n*G) == 2 * inf == inf
|
||||
a = 4a0fd63f894499928e4b2b72aced45cfc589976f4ff86f78c904d59da9379a62b702d968c1184834c11db28c7356ceb6, be113b04484cd4bc215a9f2a33a674c3764c38ca4de135dd50ce8dcf3c85d55a5aad0e171860bdb6c58201e6212d9ac5, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 4a0fd63f894499928e4b2b72aced45cfc589976f4ff86f78c904d59da9379a62b702d968c1184834c11db28c7356ceb6, be113b04484cd4bc215a9f2a33a674c3764c38ca4de135dd50ce8dcf3c85d55a5aad0e171860bdb6c58201e6212d9ac5, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# inf (n*G) + inf == 2 * inf == inf
|
||||
a = 4a0fd63f894499928e4b2b72aced45cfc589976f4ff86f78c904d59da9379a62b702d968c1184834c11db28c7356ceb6, be113b04484cd4bc215a9f2a33a674c3764c38ca4de135dd50ce8dcf3c85d55a5aad0e171860bdb6c58201e6212d9ac5, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# inf + inf (n*G) == 2 * inf == inf
|
||||
a = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 4a0fd63f894499928e4b2b72aced45cfc589976f4ff86f78c904d59da9379a62b702d968c1184834c11db28c7356ceb6, be113b04484cd4bc215a9f2a33a674c3764c38ca4de135dd50ce8dcf3c85d55a5aad0e171860bdb6c58201e6212d9ac5, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
r = inf
|
||||
|
||||
# G + inf == G
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
r = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe
|
||||
|
||||
# G + inf (n*G) == G
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = 4a0fd63f894499928e4b2b72aced45cfc589976f4ff86f78c904d59da9379a62b702d968c1184834c11db28c7356ceb6, be113b04484cd4bc215a9f2a33a674c3764c38ca4de135dd50ce8dcf3c85d55a5aad0e171860bdb6c58201e6212d9ac5, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
r = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe
|
||||
|
||||
# inf + G == G
|
||||
a = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe
|
||||
|
||||
# inf (n*G) + G == G
|
||||
a = 4a0fd63f894499928e4b2b72aced45cfc589976f4ff86f78c904d59da9379a62b702d968c1184834c11db28c7356ceb6, be113b04484cd4bc215a9f2a33a674c3764c38ca4de135dd50ce8dcf3c85d55a5aad0e171860bdb6c58201e6212d9ac5, 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe
|
||||
|
||||
# G + G == 2*G
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = db93b776427460c39c90a4fd2de4b506da821495f0687f503504e6f0ff9d48a18e6c8f2e022b53f0c8229e55783dde91, e34947f7123df0c2070d430900b0e68409f1fe415172bad915e4f18bdc588258e8e8e4a8c2aaccd842ea84633140bfda
|
||||
|
||||
# (n-1)*G + G == inf; note that -G is (n-1)*G
|
||||
a = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
b = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = inf
|
||||
|
||||
# G + (n-1)*G == inf; note that -G is (n-1)*G
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = inf
|
||||
|
||||
# (n-1)*G + (n-1)*G == 2*(n-1)*G
|
||||
a = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
b = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = db93b776427460c39c90a4fd2de4b506da821495f0687f503504e6f0ff9d48a18e6c8f2e022b53f0c8229e55783dde91, 1cb6b808edc20f3df8f2bcf6ff4f197bf60e01beae8d4526ea1b0e7423a77da617171b563d553327bd157b9dcebf4025
|
||||
|
||||
# (n-1)*G (affine) + (n-1)*G == 2*(n-1)*G
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, d487543da5ea3a16227ffdd9c69657bf393cade6970b0026745218a9d17c4fae5e40573f844b5653dcfbc253b4fc5b01, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = db93b776427460c39c90a4fd2de4b506da821495f0687f503504e6f0ff9d48a18e6c8f2e022b53f0c8229e55783dde91, 1cb6b808edc20f3df8f2bcf6ff4f197bf60e01beae8d4526ea1b0e7423a77da617171b563d553327bd157b9dcebf4025
|
||||
|
||||
# (n-1)*G + -(n-1)*G == inf
|
||||
a = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
b = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, a847d35ead83a5fe487437334601418be874fb4839021e3e3b1065ddf3bcdf43a9f34f86abdda95c6ff209e4ef82193a, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = inf
|
||||
|
||||
# -(n-1)*G + (n-1)*G == inf
|
||||
a = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, a847d35ead83a5fe487437334601418be874fb4839021e3e3b1065ddf3bcdf43a9f34f86abdda95c6ff209e4ef82193a, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
b = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = inf
|
||||
|
||||
# -(n-1)*G (affine) + (n-1)*G == inf
|
||||
a = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, a847d35ead83a5fe487437334601418be874fb4839021e3e3b1065ddf3bcdf43a9f34f86abdda95c6ff209e4ef82193a, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
b = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = inf
|
||||
|
||||
# -(n-1)*G + -G == inf; note that -G is (n-1)*G (affine)
|
||||
a = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, a847d35ead83a5fe487437334601418be874fb4839021e3e3b1065ddf3bcdf43a9f34f86abdda95c6ff209e4ef82193a, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
b = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, d487543da5ea3a16227ffdd9c69657bf393cade6970b0026745218a9d17c4fae5e40573f844b5653dcfbc253b4fc5b01, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = inf
|
||||
|
||||
# -G + -(n-1)*G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, d487543da5ea3a16227ffdd9c69657bf393cade6970b0026745218a9d17c4fae5e40573f844b5653dcfbc253b4fc5b01, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, a847d35ead83a5fe487437334601418be874fb4839021e3e3b1065ddf3bcdf43a9f34f86abdda95c6ff209e4ef82193a, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = inf
|
||||
|
||||
# (n-1)*G + -G; == -2*G; note that -G == (n-1)*G (affine)
|
||||
a = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
b = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, d487543da5ea3a16227ffdd9c69657bf393cade6970b0026745218a9d17c4fae5e40573f844b5653dcfbc253b4fc5b01, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = db93b776427460c39c90a4fd2de4b506da821495f0687f503504e6f0ff9d48a18e6c8f2e022b53f0c8229e55783dde91, 1cb6b808edc20f3df8f2bcf6ff4f197bf60e01beae8d4526ea1b0e7423a77da617171b563d553327bd157b9dcebf4025
|
||||
|
||||
# -G + (n-1)*G == -2*G; note that -G is (n-1)*G (affine)
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, d487543da5ea3a16227ffdd9c69657bf393cade6970b0026745218a9d17c4fae5e40573f844b5653dcfbc253b4fc5b01, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = db93b776427460c39c90a4fd2de4b506da821495f0687f503504e6f0ff9d48a18e6c8f2e022b53f0c8229e55783dde91, 1cb6b808edc20f3df8f2bcf6ff4f197bf60e01beae8d4526ea1b0e7423a77da617171b563d553327bd157b9dcebf4025
|
||||
|
||||
# (n-1)*G + -G == -2*G; note that -G is (n-1)*G (affine)
|
||||
a = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
b = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, d487543da5ea3a16227ffdd9c69657bf393cade6970b0026745218a9d17c4fae5e40573f844b5653dcfbc253b4fc5b01, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = db93b776427460c39c90a4fd2de4b506da821495f0687f503504e6f0ff9d48a18e6c8f2e022b53f0c8229e55783dde91, 1cb6b808edc20f3df8f2bcf6ff4f197bf60e01beae8d4526ea1b0e7423a77da617171b563d553327bd157b9dcebf4025
|
||||
|
||||
# -G + (n-1)*G == -2*G; note that -G = (n-1)*G
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, d487543da5ea3a16227ffdd9c69657bf393cade6970b0026745218a9d17c4fae5e40573f844b5653dcfbc253b4fc5b01, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = f3ee335326d22614d01b5d7cd0be73f1bfdd75982c9c273f72d0abfeecbca0431601a1bcafcdeb07e21ecf4d91c7b520, 57b82ca1527c5a01b78bc8ccb9febe74178b04b7c6fde1c1c4ef9a220c4320bb560cb078542256a3900df61c107de6c5, 53b3adc887551c0e17c07ecb42d1a5ec105aeec6b0f040a936ed4f756e83939226232b4e11191b3eb1d841c650682ca0
|
||||
r = db93b776427460c39c90a4fd2de4b506da821495f0687f503504e6f0ff9d48a18e6c8f2e022b53f0c8229e55783dde91, 1cb6b808edc20f3df8f2bcf6ff4f197bf60e01beae8d4526ea1b0e7423a77da617171b563d553327bd157b9dcebf4025
|
||||
|
||||
# -G + G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, d487543da5ea3a16227ffdd9c69657bf393cade6970b0026745218a9d17c4fae5e40573f844b5653dcfbc253b4fc5b01, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = inf
|
||||
|
||||
# G + -G == inf; note that -G is (n-1)*G (affine)
|
||||
a = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, 2b78abc25a15c5e9dd8002263969a840c6c3521968f4ffd98bade7562e83b050a1bfa8bf7bb4a9ac23043dad4b03a4fe, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
b = 4d3aadc2299e1513812ff723614ede2b6454868459a30eff879c3afc541b4d6e20e378e2a0d6ce383dd0756649c0b528, d487543da5ea3a16227ffdd9c69657bf393cade6970b0026745218a9d17c4fae5e40573f844b5653dcfbc253b4fc5b01, 000000000000000000000000000000000000000000000000000000000000000100000000ffffffffffffffff00000001
|
||||
r = inf
|
||||
32
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_scalar_mul_tests.txt
vendored
Normal file
32
zeroidc/vendor/ring/src/ec/suite_b/ops/p384_scalar_mul_tests.txt
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
a = 00
|
||||
b = 00
|
||||
r = 00
|
||||
|
||||
a = 00
|
||||
b = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972
|
||||
r = 00
|
||||
|
||||
a = 01
|
||||
b = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972
|
||||
r = caa357821c6244e05eafdf931b0e6b53872b45a79929e877e4c3adcae9998bc585acc2c6a24bb9ca8be13114da045062
|
||||
|
||||
a = 02
|
||||
b = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972
|
||||
r = 9546af0438c489c0bd5fbf26361cd6a70e568b4f3253d0f002240e13defbe9abb33f77dafbe6cc1a2ad648bee7437751
|
||||
|
||||
a = 03
|
||||
b = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972
|
||||
r = 5fea06865526cea11c0f9eb9512b41fa9581d0f6cb7db9681f846e5cd45e4791e0d22cef5581de69c9cb6068f4829e40
|
||||
|
||||
a = 7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd76760cb5666294b9
|
||||
b = 02
|
||||
r = caa357821c6244e05eafdf931b0e6b53872b45a79929e877e4c3adcae9998bc585acc2c6a24bb9ca8be13114da045062
|
||||
|
||||
a = 7fffffffffffffffffffffffffffffffffffffffffffffffe3b1a6c0fa1b96efac0d06d9245853bd76760cb5666294ba
|
||||
b = 02
|
||||
r = 355ca87de39dbb1fa150206ce4f194ac78d4ba5866d61787e29f9fb70a9da219d26d4aeba664edb0610ae855f2c0d911
|
||||
|
||||
a = 800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
b = 02
|
||||
r = 01
|
||||
203
zeroidc/vendor/ring/src/ec/suite_b/private_key.rs
vendored
Normal file
203
zeroidc/vendor/ring/src/ec/suite_b/private_key.rs
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Functionality shared by operations on private keys (ECC keygen and
|
||||
//! ECDSA signing).
|
||||
|
||||
use super::{ops::*, verify_affine_point_is_on_the_curve};
|
||||
use crate::{
|
||||
arithmetic::montgomery::R,
|
||||
ec, error,
|
||||
limb::{self, LIMB_BYTES},
|
||||
rand,
|
||||
};
|
||||
|
||||
/// Generates a random scalar in the range [1, n).
|
||||
pub fn random_scalar(
|
||||
ops: &PrivateKeyOps,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
) -> Result<Scalar, error::Unspecified> {
|
||||
let num_limbs = ops.common.num_limbs;
|
||||
let mut bytes = [0; ec::SCALAR_MAX_BYTES];
|
||||
let bytes = &mut bytes[..(num_limbs * LIMB_BYTES)];
|
||||
generate_private_scalar_bytes(ops, rng, bytes)?;
|
||||
scalar_from_big_endian_bytes(ops, bytes)
|
||||
}
|
||||
|
||||
pub fn generate_private_scalar_bytes(
|
||||
ops: &PrivateKeyOps,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
out: &mut [u8],
|
||||
) -> Result<(), error::Unspecified> {
|
||||
// [NSA Suite B Implementer's Guide to ECDSA] Appendix A.1.2, and
|
||||
// [NSA Suite B Implementer's Guide to NIST SP 800-56A] Appendix B.2,
|
||||
// "Key Pair Generation by Testing Candidates".
|
||||
//
|
||||
// [NSA Suite B Implementer's Guide to ECDSA]: doc/ecdsa.pdf.
|
||||
// [NSA Suite B Implementer's Guide to NIST SP 800-56A]: doc/ecdh.pdf.
|
||||
|
||||
// TODO: The NSA guide also suggests, in appendix B.1, another mechanism
|
||||
// that would avoid the need to use `rng.fill()` more than once. It works
|
||||
// by generating an extra 64 bits of random bytes and then reducing the
|
||||
// output (mod n). Supposedly, this removes enough of the bias towards
|
||||
// small values from the modular reduction, but it isn't obvious that it is
|
||||
// sufficient. TODO: Figure out what we can do to mitigate the bias issue
|
||||
// and switch to the other mechanism.
|
||||
|
||||
let candidate = out;
|
||||
|
||||
// XXX: The value 100 was chosen to match OpenSSL due to uncertainty of
|
||||
// what specific value would be better, but it seems bad to try 100 times.
|
||||
for _ in 0..100 {
|
||||
// NSA Guide Steps 1, 2, and 3.
|
||||
//
|
||||
// Since we calculate the length ourselves, it is pointless to check
|
||||
// it, since we can only check it by doing the same calculation.
|
||||
|
||||
// NSA Guide Step 4.
|
||||
//
|
||||
// The requirement that the random number generator has the
|
||||
// requested security strength is delegated to `rng`.
|
||||
rng.fill(candidate)?;
|
||||
|
||||
// NSA Guide Steps 5, 6, and 7.
|
||||
if check_scalar_big_endian_bytes(ops, candidate).is_err() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// NSA Guide Step 8 is done in `public_from_private()`.
|
||||
|
||||
// NSA Guide Step 9.
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Err(error::Unspecified)
|
||||
}
|
||||
|
||||
// The underlying X25519 and Ed25519 code uses an [u8; 32] to store the private
|
||||
// key. To make the ECDH and ECDSA code similar to that, we also store the
|
||||
// private key that way, which means we have to convert it to a Scalar whenever
|
||||
// we need to use it.
|
||||
#[inline]
|
||||
pub fn private_key_as_scalar(ops: &PrivateKeyOps, private_key: &ec::Seed) -> Scalar {
|
||||
// This cannot fail because we know the private key is valid.
|
||||
scalar_from_big_endian_bytes(ops, private_key.bytes_less_safe()).unwrap()
|
||||
}
|
||||
|
||||
pub fn check_scalar_big_endian_bytes(
|
||||
ops: &PrivateKeyOps,
|
||||
bytes: &[u8],
|
||||
) -> Result<(), error::Unspecified> {
|
||||
debug_assert_eq!(bytes.len(), ops.common.num_limbs * LIMB_BYTES);
|
||||
scalar_from_big_endian_bytes(ops, bytes).map(|_| ())
|
||||
}
|
||||
|
||||
// Parses a fixed-length (zero-padded) big-endian-encoded scalar in the range
|
||||
// [1, n). This is constant-time with respect to the actual value *only if* the
|
||||
// value is actually in range. In other words, this won't leak anything about a
|
||||
// valid value, but it might leak small amounts of information about an invalid
|
||||
// value (which constraint it failed).
|
||||
pub fn scalar_from_big_endian_bytes(
|
||||
ops: &PrivateKeyOps,
|
||||
bytes: &[u8],
|
||||
) -> Result<Scalar, error::Unspecified> {
|
||||
// [NSA Suite B Implementer's Guide to ECDSA] Appendix A.1.2, and
|
||||
// [NSA Suite B Implementer's Guide to NIST SP 800-56A] Appendix B.2,
|
||||
// "Key Pair Generation by Testing Candidates".
|
||||
//
|
||||
// [NSA Suite B Implementer's Guide to ECDSA]: doc/ecdsa.pdf.
|
||||
// [NSA Suite B Implementer's Guide to NIST SP 800-56A]: doc/ecdh.pdf.
|
||||
//
|
||||
// Steps 5, 6, and 7.
|
||||
//
|
||||
// XXX: The NSA guide says that we should verify that the random scalar is
|
||||
// in the range [0, n - 1) and then add one to it so that it is in the range
|
||||
// [1, n). Instead, we verify that the scalar is in the range [1, n). This
|
||||
// way, we avoid needing to compute or store the value (n - 1), we avoid the
|
||||
// need to implement a function to add one to a scalar, and we avoid needing
|
||||
// to convert the scalar back into an array of bytes.
|
||||
scalar_parse_big_endian_fixed_consttime(ops.common, untrusted::Input::from(bytes))
|
||||
}
|
||||
|
||||
pub fn public_from_private(
|
||||
ops: &PrivateKeyOps,
|
||||
public_out: &mut [u8],
|
||||
my_private_key: &ec::Seed,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
let elem_and_scalar_bytes = ops.common.num_limbs * LIMB_BYTES;
|
||||
debug_assert_eq!(public_out.len(), 1 + (2 * elem_and_scalar_bytes));
|
||||
let my_private_key = private_key_as_scalar(ops, my_private_key);
|
||||
let my_public_key = ops.point_mul_base(&my_private_key);
|
||||
public_out[0] = 4; // Uncompressed encoding.
|
||||
let (x_out, y_out) = (&mut public_out[1..]).split_at_mut(elem_and_scalar_bytes);
|
||||
|
||||
// `big_endian_affine_from_jacobian` verifies that the point is not at
|
||||
// infinity and is on the curve.
|
||||
big_endian_affine_from_jacobian(ops, Some(x_out), Some(y_out), &my_public_key)
|
||||
}
|
||||
|
||||
pub fn affine_from_jacobian(
|
||||
ops: &PrivateKeyOps,
|
||||
p: &Point,
|
||||
) -> Result<(Elem<R>, Elem<R>), error::Unspecified> {
|
||||
let z = ops.common.point_z(p);
|
||||
|
||||
// Since we restrict our private key to the range [1, n), the curve has
|
||||
// prime order, and we verify that the peer's point is on the curve,
|
||||
// there's no way that the result can be at infinity. But, use `assert!`
|
||||
// instead of `debug_assert!` anyway
|
||||
assert!(ops.common.elem_verify_is_not_zero(&z).is_ok());
|
||||
|
||||
let x = ops.common.point_x(p);
|
||||
let y = ops.common.point_y(p);
|
||||
|
||||
let zz_inv = ops.elem_inverse_squared(&z);
|
||||
|
||||
let x_aff = ops.common.elem_product(&x, &zz_inv);
|
||||
|
||||
// `y_aff` is needed to validate the point is on the curve. It is also
|
||||
// needed in the non-ECDH case where we need to output it.
|
||||
let y_aff = {
|
||||
let zzzz_inv = ops.common.elem_squared(&zz_inv);
|
||||
let zzz_inv = ops.common.elem_product(&z, &zzzz_inv);
|
||||
ops.common.elem_product(&y, &zzz_inv)
|
||||
};
|
||||
|
||||
// If we validated our inputs correctly and then computed (x, y, z), then
|
||||
// (x, y, z) will be on the curve. See
|
||||
// `verify_affine_point_is_on_the_curve_scaled` for the motivation.
|
||||
verify_affine_point_is_on_the_curve(ops.common, (&x_aff, &y_aff))?;
|
||||
|
||||
Ok((x_aff, y_aff))
|
||||
}
|
||||
|
||||
pub fn big_endian_affine_from_jacobian(
|
||||
ops: &PrivateKeyOps,
|
||||
x_out: Option<&mut [u8]>,
|
||||
y_out: Option<&mut [u8]>,
|
||||
p: &Point,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
let (x_aff, y_aff) = affine_from_jacobian(ops, p)?;
|
||||
let num_limbs = ops.common.num_limbs;
|
||||
if let Some(x_out) = x_out {
|
||||
let x = ops.common.elem_unencoded(&x_aff);
|
||||
limb::big_endian_from_limbs(&x.limbs[..num_limbs], x_out);
|
||||
}
|
||||
if let Some(y_out) = y_out {
|
||||
let y = ops.common.elem_unencoded(&y_aff);
|
||||
limb::big_endian_from_limbs(&y.limbs[..num_limbs], y_out);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
107
zeroidc/vendor/ring/src/ec/suite_b/public_key.rs
vendored
Normal file
107
zeroidc/vendor/ring/src/ec/suite_b/public_key.rs
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Functionality shared by operations on public keys (ECDSA verification and
|
||||
//! ECDH agreement).
|
||||
|
||||
use super::{ops::*, verify_affine_point_is_on_the_curve};
|
||||
use crate::{arithmetic::montgomery::*, error};
|
||||
|
||||
/// Parses a public key encoded in uncompressed form. The key is validated
|
||||
/// using the ECC Partial Public-Key Validation Routine from
|
||||
/// [NIST SP 800-56A, revision 2] Section 5.6.2.3.3, the NSA's
|
||||
/// "Suite B Implementer's Guide to NIST SP 800-56A," Appendix B.3, and the
|
||||
/// NSA's "Suite B Implementer's Guide to FIPS 186-3 (ECDSA)," Appendix A.3.
|
||||
///
|
||||
/// [NIST SP 800-56A, revision 2]:
|
||||
/// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf
|
||||
pub fn parse_uncompressed_point(
|
||||
ops: &PublicKeyOps,
|
||||
input: untrusted::Input,
|
||||
) -> Result<(Elem<R>, Elem<R>), error::Unspecified> {
|
||||
// NIST SP 800-56A Step 1: "Verify that Q is not the point at infinity.
|
||||
// This can be done by inspection if the point is entered in the standard
|
||||
// affine representation." (We do it by inspection since we only accept
|
||||
// the affine representation.)
|
||||
let (x, y) = input.read_all(error::Unspecified, |input| {
|
||||
// The encoding must be 4, which is the encoding for "uncompressed".
|
||||
let encoding = input.read_byte()?;
|
||||
if encoding != 4 {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
// NIST SP 800-56A Step 2: "Verify that xQ and yQ are integers in the
|
||||
// interval [0, p-1] in the case that q is an odd prime p[.]"
|
||||
let x = ops.elem_parse(input)?;
|
||||
let y = ops.elem_parse(input)?;
|
||||
Ok((x, y))
|
||||
})?;
|
||||
|
||||
// NIST SP 800-56A Step 3: "If q is an odd prime p, verify that
|
||||
// yQ**2 = xQ**3 + axQ + b in GF(p), where the arithmetic is performed
|
||||
// modulo p."
|
||||
verify_affine_point_is_on_the_curve(ops.common, (&x, &y))?;
|
||||
|
||||
// NIST SP 800-56A Note: "Since its order is not verified, there is no
|
||||
// check that the public key is in the correct EC subgroup."
|
||||
//
|
||||
// NSA Suite B Implementer's Guide Note: "ECC Full Public-Key Validation
|
||||
// includes an additional check to ensure that the point has the correct
|
||||
// order. This check is not necessary for curves having prime order (and
|
||||
// cofactor h = 1), such as P-256 and P-384."
|
||||
|
||||
Ok((x, y))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{super::ops, *};
|
||||
use crate::test;
|
||||
|
||||
#[test]
|
||||
fn parse_uncompressed_point_test() {
|
||||
test::run(
|
||||
test_file!("suite_b_public_key_tests.txt"),
|
||||
|section, test_case| {
|
||||
assert_eq!(section, "");
|
||||
|
||||
let curve_name = test_case.consume_string("Curve");
|
||||
|
||||
let public_key = test_case.consume_bytes("Q");
|
||||
let public_key = untrusted::Input::from(&public_key);
|
||||
let is_valid = test_case.consume_string("Result") == "P";
|
||||
|
||||
let curve_ops = public_key_ops_from_curve_name(&curve_name);
|
||||
|
||||
let result = parse_uncompressed_point(curve_ops, public_key);
|
||||
assert_eq!(is_valid, result.is_ok());
|
||||
|
||||
// TODO: Verify that we when we re-serialize the parsed (x, y), the
|
||||
// output is equal to the input.
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn public_key_ops_from_curve_name(curve_name: &str) -> &'static PublicKeyOps {
|
||||
if curve_name == "P-256" {
|
||||
&ops::p256::PUBLIC_KEY_OPS
|
||||
} else if curve_name == "P-384" {
|
||||
&ops::p384::PUBLIC_KEY_OPS
|
||||
} else {
|
||||
panic!("Unsupported curve: {}", curve_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
233
zeroidc/vendor/ring/src/ec/suite_b/suite_b_public_key_tests.txt
vendored
Normal file
233
zeroidc/vendor/ring/src/ec/suite_b/suite_b_public_key_tests.txt
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
# Test vectors for public key validation.
|
||||
|
||||
# Invalid Curve Attack from
|
||||
# https://web-in-security.blogspot.ca/2015/09/practical-invalid-curve-attacks.html
|
||||
# https://www.nds.rub.de/media/nds/veroeffentlichungen/2015/09/14/main-full.pdf
|
||||
Curve = P-256
|
||||
Q = 04b70bf043c144935756f8f4578c369cf960ee510a5a0f90e93a373a21f0d1397f4a2e0ded57a5156bb82eb4314c37fd4155395a7e51988af289cce531b9c17192
|
||||
Result = F
|
||||
|
||||
|
||||
# Test vectors for Public Key Point Validation.
|
||||
#
|
||||
# These test vectors were generated by applying the patch in
|
||||
# util/generate-tests.patch to BoringSSL, and then running
|
||||
# `bssl generate-tests ecc-public-key`.
|
||||
#
|
||||
|
||||
# X == 0, decompressed with y_bit == 0. This verifies that the
|
||||
# implementation doesn't reject zero-valued field elements (they
|
||||
# aren't scalars).
|
||||
Curve = P-256
|
||||
Q = 04000000000000000000000000000000000000000000000000000000000000000066485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4
|
||||
Result = P
|
||||
|
||||
# X == q. This is invalid because q isn't a valid field element. Some
|
||||
# broken implementations might accept this if they reduce X mod q
|
||||
# since q mod q == 0 and the Y coordinate matches the one from the
|
||||
# x == 0 test case above.
|
||||
Curve = P-256
|
||||
Q = 04ffffffff00000001000000000000000000000000ffffffffffffffffffffffff66485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4
|
||||
Result = F (X is out of range)
|
||||
|
||||
# X == 0, decompressed with y_bit == 1.
|
||||
Curve = P-256
|
||||
Q = 04000000000000000000000000000000000000000000000000000000000000000099b7a386f1d07c29dbcc42a27b5f9449abe3d50de25178e8d7407a95e8b06c0b
|
||||
Result = P
|
||||
|
||||
# X == q, decompressed with y_bit == 1. See the previous X == q test
|
||||
# case.
|
||||
Curve = P-256
|
||||
Q = 04ffffffff00000001000000000000000000000000ffffffffffffffffffffffff99b7a386f1d07c29dbcc42a27b5f9449abe3d50de25178e8d7407a95e8b06c0b
|
||||
Result = F (X is out of range)
|
||||
|
||||
# The largest valid X coordinate, decompressed with y_bit == 0. This
|
||||
# helps ensure that the upper bound on coordinate values is not too
|
||||
# low.
|
||||
Curve = P-256
|
||||
Q = 04ffffffff00000001000000000000000000000000fffffffffffffffffffffffce68e641309515ec1da369202838e0adda2b37040614a5f5460c616e871aa3ede
|
||||
Result = P
|
||||
|
||||
# X == 0, decompressed with y_bit == 0. This verifies that the
|
||||
# implementation doesn't reject zero-valued field elements (they
|
||||
# aren't scalars).
|
||||
Curve = P-384
|
||||
Q = 040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003cf99ef04f51a5ea630ba3f9f960dd593a14c9be39fd2bd215d3b4b08aaaf86bbf927f2c46e52ab06fb742b8850e521e
|
||||
Result = P
|
||||
|
||||
# X == q. This is invalid because q isn't a valid field element. Some
|
||||
# broken implementations might accept this if they reduce X mod q
|
||||
# since q mod q == 0 and the Y coordinate matches the one from the
|
||||
# x == 0 test case above.
|
||||
Curve = P-384
|
||||
Q = 04fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff3cf99ef04f51a5ea630ba3f9f960dd593a14c9be39fd2bd215d3b4b08aaaf86bbf927f2c46e52ab06fb742b8850e521e
|
||||
Result = F (X is out of range)
|
||||
|
||||
# X == 0, decompressed with y_bit == 1.
|
||||
Curve = P-384
|
||||
Q = 04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c306610fb0ae5a159cf45c06069f22a6c5eb3641c602d42dea2c4b4f75550793406d80d2b91ad54f9048bd487af1ade1
|
||||
Result = P
|
||||
|
||||
# X == q, decompressed with y_bit == 1. See the previous X == q test
|
||||
# case.
|
||||
Curve = P-384
|
||||
Q = 04fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffffc306610fb0ae5a159cf45c06069f22a6c5eb3641c602d42dea2c4b4f75550793406d80d2b91ad54f9048bd487af1ade1
|
||||
Result = F (X is out of range)
|
||||
|
||||
# The largest valid X coordinate, decompressed with y_bit == 0. This
|
||||
# helps ensure that the upper bound on coordinate values is not too
|
||||
# low.
|
||||
Curve = P-384
|
||||
Q = 04fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffe8cdeadbbd04911a3c1931e26df3fa6439dca9c7eb286fbd46fc319f0e2bb780232baf57825fc0c1912ada2fefe84024c
|
||||
Result = P
|
||||
|
||||
|
||||
# RFC 5903 (IKE and IKEv2 ECDH) Test Vectors
|
||||
# Q is (grx, gry) in uncompressed encoding.
|
||||
|
||||
Curve = P-256
|
||||
Q = 04D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB
|
||||
Result = P
|
||||
|
||||
Curve = P-384
|
||||
Q = 04E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C
|
||||
Result = P
|
||||
|
||||
# Tweaks of the RFC 5903 vectors for testing malformed (syntactically) public
|
||||
# keys
|
||||
|
||||
Curve = P-256
|
||||
Q = ""
|
||||
Result = F (Peer public key is empty.)
|
||||
|
||||
Curve = P-384
|
||||
Q = ""
|
||||
Result = F (Peer public key is empty.)
|
||||
|
||||
Curve = P-256
|
||||
Q = 00
|
||||
Result = F (Peer public key is the special encoding of the point at infinity.)
|
||||
|
||||
Curve = P-384
|
||||
Q = 00
|
||||
Result = F (Peer public key is the special encoding of the point at infinity.)
|
||||
|
||||
Curve = P-256
|
||||
Q = 01
|
||||
Result = F (Peer public key consists of (only) an invalid encoding indicator.)
|
||||
|
||||
Curve = P-384
|
||||
Q = 01
|
||||
Result = F (Peer public key consists of (only) an invalid encoding indicator.)
|
||||
|
||||
Curve = P-256
|
||||
Q = 02
|
||||
Result = F (Peer public key consists of (only) a compressed encoding indicator (0x02).)
|
||||
|
||||
Curve = P-384
|
||||
Q = 02
|
||||
Result = F (Peer public key consists of (only) a compressed encoding indicator (0x02).)
|
||||
|
||||
Curve = P-256
|
||||
Q = 03
|
||||
Result = F (Peer public key consists of (only) a compressed encoding indicator (0x03).)
|
||||
|
||||
Curve = P-384
|
||||
Q = 03
|
||||
Result = F (Peer public key consists of (only) a compressed encoding indicator (0x03).)
|
||||
|
||||
Curve = P-256
|
||||
Q = 04
|
||||
Result = F (Peer public key consists of (only) a uncompressed encoding indicator.)
|
||||
|
||||
Curve = P-384
|
||||
Q = 04
|
||||
Result = F (Peer public key consists of (only) a compressed encoding indicator.)
|
||||
|
||||
Curve = P-256
|
||||
Q = 04
|
||||
Result = F (Peer public key consists of (only) an invalid encoding indicator (0x05).)
|
||||
|
||||
Curve = P-384
|
||||
Q = 04
|
||||
Result = F (Peer public key consists of (only) an invalid encoding indicator (0x05).)
|
||||
|
||||
Curve = P-256
|
||||
Q = 01D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB
|
||||
Result = F (Peer public key starts with a completely invalid encoding indicator byte (0x01).)
|
||||
|
||||
Curve = P-384
|
||||
Q = 01E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C
|
||||
Result = F (Peer public key starts with a completely invalid encoding indicator byte (0x01).)
|
||||
|
||||
Curve = P-256
|
||||
Q = 02D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB
|
||||
Result = F (Peer public key encoding's first byte is 0x02, should be 0x04.)
|
||||
|
||||
Curve = P-384
|
||||
Q = 02E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C
|
||||
Result = F (Peer public key encoding's first byte is 0x02, should be 0x04.)
|
||||
|
||||
Curve = P-256
|
||||
Q = 03D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB
|
||||
Result = F (Peer public key encoding's first byte is 0x03, should be 0x04.)
|
||||
|
||||
Curve = P-384
|
||||
Q = 03E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C
|
||||
Result = F (Peer public key encoding's first byte is 0x03, should be 0x04.)
|
||||
|
||||
Curve = P-256
|
||||
Q = 05D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB
|
||||
Result = F (Peer public key starts with a completely invalid encoding indicator byte (0x05).)
|
||||
|
||||
Curve = P-384
|
||||
Q = 05E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C
|
||||
Result = F (Peer public key starts with a completely invalid encoding indicator byte (0x05).)
|
||||
|
||||
Curve = P-256
|
||||
Q = FFD12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB
|
||||
Result = F (Peer public key starts with a completely invalid encoding indicator byte (0xff).)
|
||||
|
||||
Curve = P-384
|
||||
Q = FFE558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C
|
||||
Result = F (Peer public key starts with a completely invalid encoding indicator byte (0xff).)
|
||||
|
||||
Curve = P-256
|
||||
Q = D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB
|
||||
Result = F (Peer public key is missing the encoding indicator byte.)
|
||||
|
||||
Curve = P-384
|
||||
Q = E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C
|
||||
Result = F (Peer public key is missing the encoding indicator byte.)
|
||||
|
||||
Curve = P-256
|
||||
Q = 04D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872
|
||||
Result = F (Peer public key has the last byte truncated.)
|
||||
|
||||
Curve = P-384
|
||||
Q = 04E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E638
|
||||
Result = F (Peer public key has the last byte truncated.)
|
||||
|
||||
Curve = P-256
|
||||
Q = 04D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63
|
||||
Result = F (Peer public key is missing the Y coordinate completely.)
|
||||
|
||||
Curve = P-384
|
||||
Q = 04E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571
|
||||
Result = F (Peer public key is missing the Y coordinate completely.)
|
||||
|
||||
Curve = P-256
|
||||
Q = 02D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63
|
||||
Result = F (Peer public key is in compressed form (0x02).)
|
||||
|
||||
Curve = P-384
|
||||
Q = 02E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571
|
||||
Result = F (Peer public key is in compressed form (0x02).)
|
||||
|
||||
Curve = P-256
|
||||
Q = 03D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63
|
||||
Result = F (Peer public key is in compressed form (0x03).)
|
||||
|
||||
Curve = P-384
|
||||
Q = 03E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571
|
||||
Result = F (Peer public key is in compressed form (0x03).)
|
||||
154
zeroidc/vendor/ring/src/endian.rs
vendored
Normal file
154
zeroidc/vendor/ring/src/endian.rs
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
use core::num::Wrapping;
|
||||
|
||||
/// An `Encoding` of a type `T` can be converted to/from its byte
|
||||
/// representation without any byte swapping or other computation.
|
||||
///
|
||||
/// The `Self: Copy` constraint addresses `clippy::declare_interior_mutable_const`.
|
||||
pub trait Encoding<T>: From<T> + Into<T>
|
||||
where
|
||||
Self: Copy,
|
||||
{
|
||||
const ZERO: Self;
|
||||
}
|
||||
|
||||
/// Allow access to a slice of of `Encoding<T>` as a slice of bytes.
|
||||
pub fn as_byte_slice<E: Encoding<T>, T>(x: &[E]) -> &[u8] {
|
||||
unsafe {
|
||||
core::slice::from_raw_parts(x.as_ptr() as *const u8, x.len() * core::mem::size_of::<E>())
|
||||
}
|
||||
}
|
||||
|
||||
/// Work around the inability to implement `AsRef` for arrays of `Encoding`s
|
||||
/// due to the coherence rules.
|
||||
pub trait ArrayEncoding<T> {
|
||||
fn as_byte_array(&self) -> &T;
|
||||
}
|
||||
|
||||
/// Work around the inability to implement `from` for arrays of `Encoding`s
|
||||
/// due to the coherence rules.
|
||||
pub trait FromByteArray<T> {
|
||||
fn from_byte_array(a: &T) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! define_endian {
|
||||
($endian:ident) => {
|
||||
#[repr(transparent)]
|
||||
pub struct $endian<T>(T);
|
||||
|
||||
impl<T> $endian<T> {
|
||||
#[deprecated]
|
||||
pub fn into_raw_value(self) -> T {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Copy for $endian<T> where T: Copy {}
|
||||
|
||||
impl<T> Clone for $endian<T>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_from_byte_array {
|
||||
($endian:ident, $base:ident, $elems:expr) => {
|
||||
impl FromByteArray<[u8; $elems * core::mem::size_of::<$base>()]>
|
||||
for [$endian<$base>; $elems]
|
||||
{
|
||||
fn from_byte_array(a: &[u8; $elems * core::mem::size_of::<$base>()]) -> Self {
|
||||
unsafe { core::mem::transmute_copy(a) }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_array_encoding {
|
||||
($endian:ident, $base:ident, $elems:expr) => {
|
||||
impl ArrayEncoding<[u8; $elems * core::mem::size_of::<$base>()]>
|
||||
for [$endian<$base>; $elems]
|
||||
{
|
||||
fn as_byte_array(&self) -> &[u8; $elems * core::mem::size_of::<$base>()] {
|
||||
// TODO: When we can require Rust 1.47.0 or later we could avoid
|
||||
// `as` and `unsafe` here using
|
||||
// `as_byte_slice(self).try_into().unwrap()`.
|
||||
let as_bytes_ptr =
|
||||
self.as_ptr() as *const [u8; $elems * core::mem::size_of::<$base>()];
|
||||
unsafe { &*as_bytes_ptr }
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_byte_array!($endian, $base, $elems);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_endian {
|
||||
($endian:ident, $base:ident, $to_endian:ident, $from_endian:ident, $size:expr) => {
|
||||
impl Encoding<$base> for $endian<$base> {
|
||||
const ZERO: Self = Self(0);
|
||||
}
|
||||
|
||||
impl From<[u8; $size]> for $endian<$base> {
|
||||
#[inline]
|
||||
fn from(bytes: [u8; $size]) -> Self {
|
||||
Self($base::from_ne_bytes(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$endian<$base>> for [u8; $size] {
|
||||
#[inline]
|
||||
fn from(encoded: $endian<$base>) -> Self {
|
||||
$base::to_ne_bytes(encoded.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$base> for $endian<$base> {
|
||||
#[inline]
|
||||
fn from(value: $base) -> Self {
|
||||
Self($base::$to_endian(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Wrapping<$base>> for $endian<$base> {
|
||||
#[inline]
|
||||
fn from(Wrapping(value): Wrapping<$base>) -> Self {
|
||||
Self($base::$to_endian(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$endian<$base>> for $base {
|
||||
#[inline]
|
||||
fn from($endian(value): $endian<$base>) -> Self {
|
||||
$base::$from_endian(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl_array_encoding!($endian, $base, 1);
|
||||
impl_array_encoding!($endian, $base, 2);
|
||||
impl_array_encoding!($endian, $base, 3);
|
||||
impl_array_encoding!($endian, $base, 4);
|
||||
impl_array_encoding!($endian, $base, 8);
|
||||
};
|
||||
}
|
||||
|
||||
define_endian!(BigEndian);
|
||||
define_endian!(LittleEndian);
|
||||
impl_endian!(BigEndian, u32, to_be, from_be, 4);
|
||||
impl_endian!(BigEndian, u64, to_be, from_be, 8);
|
||||
impl_endian!(LittleEndian, u32, to_le, from_le, 4);
|
||||
impl_endian!(LittleEndian, u64, to_le, from_le, 8);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_big_endian() {
|
||||
let x = BigEndian::from(1u32);
|
||||
assert_eq!(u32::from(x), 1);
|
||||
}
|
||||
}
|
||||
226
zeroidc/vendor/ring/src/error.rs
vendored
Normal file
226
zeroidc/vendor/ring/src/error.rs
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Error reporting.
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate std;
|
||||
|
||||
/// An error with absolutely no details.
|
||||
///
|
||||
/// *ring* uses this unit type as the error type in most of its results
|
||||
/// because (a) usually the specific reasons for a failure are obvious or are
|
||||
/// not useful to know, and/or (b) providing more details about a failure might
|
||||
/// provide a dangerous side channel, and/or (c) it greatly simplifies the
|
||||
/// error handling logic.
|
||||
///
|
||||
/// `Result<T, ring::error::Unspecified>` is mostly equivalent to
|
||||
/// `Result<T, ()>`. However, `ring::error::Unspecified` implements
|
||||
/// [`std::error::Error`] and users of *ring* can implement
|
||||
/// `From<ring::error::Unspecified>` to map this to their own error types, as
|
||||
/// described in [“Error Handling” in the Rust Book]:
|
||||
///
|
||||
/// ```
|
||||
/// use ring::rand::{self, SecureRandom};
|
||||
///
|
||||
/// enum Error {
|
||||
/// CryptoError,
|
||||
///
|
||||
/// # #[cfg(feature = "alloc")]
|
||||
/// IOError(std::io::Error),
|
||||
/// // [...]
|
||||
/// }
|
||||
///
|
||||
/// impl From<ring::error::Unspecified> for Error {
|
||||
/// fn from(_: ring::error::Unspecified) -> Self { Error::CryptoError }
|
||||
/// }
|
||||
///
|
||||
/// fn eight_random_bytes() -> Result<[u8; 8], Error> {
|
||||
/// let rng = rand::SystemRandom::new();
|
||||
/// let mut bytes = [0; 8];
|
||||
///
|
||||
/// // The `From<ring::error::Unspecified>` implementation above makes this
|
||||
/// // equivalent to
|
||||
/// // `rng.fill(&mut bytes).map_err(|_| Error::CryptoError)?`.
|
||||
/// rng.fill(&mut bytes)?;
|
||||
///
|
||||
/// Ok(bytes)
|
||||
/// }
|
||||
///
|
||||
/// assert!(eight_random_bytes().is_ok());
|
||||
/// ```
|
||||
///
|
||||
/// Experience with using and implementing other crypto libraries like has
|
||||
/// shown that sophisticated error reporting facilities often cause significant
|
||||
/// bugs themselves, both within the crypto library and within users of the
|
||||
/// crypto library. This approach attempts to minimize complexity in the hopes
|
||||
/// of avoiding such problems. In some cases, this approach may be too extreme,
|
||||
/// and it may be important for an operation to provide some details about the
|
||||
/// cause of a failure. Users of *ring* are encouraged to report such cases so
|
||||
/// that they can be addressed individually.
|
||||
///
|
||||
/// [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
|
||||
/// [“Error Handling” in the Rust Book]:
|
||||
/// https://doc.rust-lang.org/book/first-edition/error-handling.html#the-from-trait
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Unspecified;
|
||||
|
||||
impl Unspecified {
|
||||
fn description_() -> &'static str {
|
||||
"ring::error::Unspecified"
|
||||
}
|
||||
}
|
||||
|
||||
// This is required for the implementation of `std::error::Error`.
|
||||
impl core::fmt::Display for Unspecified {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
f.write_str(Self::description_())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl std::error::Error for Unspecified {
|
||||
#[inline]
|
||||
fn cause(&self) -> Option<&dyn std::error::Error> {
|
||||
None
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
Self::description_()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<untrusted::EndOfInput> for Unspecified {
|
||||
fn from(_: untrusted::EndOfInput) -> Self {
|
||||
Unspecified
|
||||
}
|
||||
}
|
||||
|
||||
impl From<core::array::TryFromSliceError> for Unspecified {
|
||||
fn from(_: core::array::TryFromSliceError) -> Self {
|
||||
Unspecified
|
||||
}
|
||||
}
|
||||
|
||||
/// An error parsing or validating a key.
|
||||
///
|
||||
/// The `Display` implementation and `<KeyRejected as Error>::description()`
|
||||
/// will return a string that will help you better understand why a key was
|
||||
/// rejected change which errors are reported in which situations while
|
||||
/// minimizing the likelihood that any applications will be broken.
|
||||
///
|
||||
/// Here is an incomplete list of reasons a key may be unsupported:
|
||||
///
|
||||
/// * Invalid or Inconsistent Components: A component of the key has an invalid
|
||||
/// value, or the mathematical relationship between two (or more) components
|
||||
/// required for a valid key does not hold.
|
||||
///
|
||||
/// * The encoding of the key is invalid. Perhaps the key isn't in the correct
|
||||
/// format; e.g. it may be Base64 ("PEM") encoded, in which case the Base64
|
||||
/// encoding needs to be undone first.
|
||||
///
|
||||
/// * The encoding includes a versioning mechanism and that mechanism indicates
|
||||
/// that the key is encoded in a version of the encoding that isn't supported.
|
||||
/// This might happen for multi-prime RSA keys (keys with more than two
|
||||
/// private prime factors), which aren't supported, for example.
|
||||
///
|
||||
/// * Too small or too Large: One of the primary components of the key is too
|
||||
/// small or two large. Too-small keys are rejected for security reasons. Some
|
||||
/// unnecessarily large keys are rejected for performance reasons.
|
||||
///
|
||||
/// * Wrong algorithm: The key is not valid for the algorithm in which it was
|
||||
/// being used.
|
||||
///
|
||||
/// * Unexpected errors: Report this as a bug.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct KeyRejected(&'static str);
|
||||
|
||||
impl KeyRejected {
|
||||
/// The value returned from <Self as std::error::Error>::description()
|
||||
pub fn description_(&self) -> &'static str {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub(crate) fn inconsistent_components() -> Self {
|
||||
KeyRejected("InconsistentComponents")
|
||||
}
|
||||
|
||||
pub(crate) fn invalid_component() -> Self {
|
||||
KeyRejected("InvalidComponent")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn invalid_encoding() -> Self {
|
||||
KeyRejected("InvalidEncoding")
|
||||
}
|
||||
|
||||
// XXX: See the comment at the call site.
|
||||
pub(crate) fn rng_failed() -> Self {
|
||||
KeyRejected("RNG failed")
|
||||
}
|
||||
|
||||
pub(crate) fn public_key_is_missing() -> Self {
|
||||
KeyRejected("PublicKeyIsMissing")
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub(crate) fn too_small() -> Self {
|
||||
KeyRejected("TooSmall")
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub(crate) fn too_large() -> Self {
|
||||
KeyRejected("TooLarge")
|
||||
}
|
||||
|
||||
pub(crate) fn version_not_supported() -> Self {
|
||||
KeyRejected("VersionNotSupported")
|
||||
}
|
||||
|
||||
pub(crate) fn wrong_algorithm() -> Self {
|
||||
KeyRejected("WrongAlgorithm")
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub(crate) fn private_modulus_len_not_multiple_of_512_bits() -> Self {
|
||||
KeyRejected("PrivateModulusLenNotMultipleOf512Bits")
|
||||
}
|
||||
|
||||
pub(crate) fn unexpected_error() -> Self {
|
||||
KeyRejected("UnexpectedError")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl std::error::Error for KeyRejected {
|
||||
fn cause(&self) -> Option<&dyn std::error::Error> {
|
||||
None
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
self.description_()
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for KeyRejected {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
f.write_str(self.description_())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KeyRejected> for Unspecified {
|
||||
fn from(_: KeyRejected) -> Self {
|
||||
Unspecified
|
||||
}
|
||||
}
|
||||
233
zeroidc/vendor/ring/src/hkdf.rs
vendored
Normal file
233
zeroidc/vendor/ring/src/hkdf.rs
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
// Copyright 2015 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! HMAC-based Extract-and-Expand Key Derivation Function.
|
||||
//!
|
||||
//! HKDF is specified in [RFC 5869].
|
||||
//!
|
||||
//! [RFC 5869]: https://tools.ietf.org/html/rfc5869
|
||||
|
||||
use crate::{error, hmac};
|
||||
|
||||
/// An HKDF algorithm.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct Algorithm(hmac::Algorithm);
|
||||
|
||||
impl Algorithm {
|
||||
/// The underlying HMAC algorithm.
|
||||
#[inline]
|
||||
pub fn hmac_algorithm(&self) -> hmac::Algorithm {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// HKDF using HMAC-SHA-1. Obsolete.
|
||||
pub static HKDF_SHA1_FOR_LEGACY_USE_ONLY: Algorithm =
|
||||
Algorithm(hmac::HMAC_SHA1_FOR_LEGACY_USE_ONLY);
|
||||
|
||||
/// HKDF using HMAC-SHA-256.
|
||||
pub static HKDF_SHA256: Algorithm = Algorithm(hmac::HMAC_SHA256);
|
||||
|
||||
/// HKDF using HMAC-SHA-384.
|
||||
pub static HKDF_SHA384: Algorithm = Algorithm(hmac::HMAC_SHA384);
|
||||
|
||||
/// HKDF using HMAC-SHA-512.
|
||||
pub static HKDF_SHA512: Algorithm = Algorithm(hmac::HMAC_SHA512);
|
||||
|
||||
impl KeyType for Algorithm {
|
||||
fn len(&self) -> usize {
|
||||
self.0.digest_algorithm().output_len
|
||||
}
|
||||
}
|
||||
|
||||
/// A salt for HKDF operations.
|
||||
#[derive(Debug)]
|
||||
pub struct Salt(hmac::Key);
|
||||
|
||||
impl Salt {
|
||||
/// Constructs a new `Salt` with the given value based on the given digest
|
||||
/// algorithm.
|
||||
///
|
||||
/// Constructing a `Salt` is relatively expensive so it is good to reuse a
|
||||
/// `Salt` object instead of re-constructing `Salt`s with the same value.
|
||||
pub fn new(algorithm: Algorithm, value: &[u8]) -> Self {
|
||||
Salt(hmac::Key::new(algorithm.0, value))
|
||||
}
|
||||
|
||||
/// The [HKDF-Extract] operation.
|
||||
///
|
||||
/// [HKDF-Extract]: https://tools.ietf.org/html/rfc5869#section-2.2
|
||||
pub fn extract(&self, secret: &[u8]) -> Prk {
|
||||
// The spec says that if no salt is provided then a key of
|
||||
// `digest_alg.output_len` bytes of zeros is used. But, HMAC keys are
|
||||
// already zero-padded to the block length, which is larger than the output
|
||||
// length of the extract step (the length of the digest). Consequently the
|
||||
// `Key` constructor will automatically do the right thing for a
|
||||
// zero-length string.
|
||||
let salt = &self.0;
|
||||
let prk = hmac::sign(salt, secret);
|
||||
Prk(hmac::Key::new(salt.algorithm(), prk.as_ref()))
|
||||
}
|
||||
|
||||
/// The algorithm used to derive this salt.
|
||||
#[inline]
|
||||
pub fn algorithm(&self) -> Algorithm {
|
||||
Algorithm(self.0.algorithm())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Okm<'_, Algorithm>> for Salt {
|
||||
fn from(okm: Okm<'_, Algorithm>) -> Self {
|
||||
Self(hmac::Key::from(Okm {
|
||||
prk: okm.prk,
|
||||
info: okm.info,
|
||||
len: okm.len().0,
|
||||
len_cached: okm.len_cached,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/// The length of the OKM (Output Keying Material) for a `Prk::expand()` call.
|
||||
pub trait KeyType {
|
||||
/// The length that `Prk::expand()` should expand its input to.
|
||||
fn len(&self) -> usize;
|
||||
}
|
||||
|
||||
/// A HKDF PRK (pseudorandom key).
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Prk(hmac::Key);
|
||||
|
||||
impl Prk {
|
||||
/// Construct a new `Prk` directly with the given value.
|
||||
///
|
||||
/// Usually one can avoid using this. It is useful when the application
|
||||
/// intentionally wants to leak the PRK secret, e.g. to implement
|
||||
/// `SSLKEYLOGFILE` functionality.
|
||||
pub fn new_less_safe(algorithm: Algorithm, value: &[u8]) -> Self {
|
||||
Self(hmac::Key::new(algorithm.hmac_algorithm(), value))
|
||||
}
|
||||
|
||||
/// The [HKDF-Expand] operation.
|
||||
///
|
||||
/// [HKDF-Expand]: https://tools.ietf.org/html/rfc5869#section-2.3
|
||||
///
|
||||
/// Fails if (and only if) `len` is too large.
|
||||
#[inline]
|
||||
pub fn expand<'a, L: KeyType>(
|
||||
&'a self,
|
||||
info: &'a [&'a [u8]],
|
||||
len: L,
|
||||
) -> Result<Okm<'a, L>, error::Unspecified> {
|
||||
let len_cached = len.len();
|
||||
if len_cached > 255 * self.0.algorithm().digest_algorithm().output_len {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
Ok(Okm {
|
||||
prk: self,
|
||||
info,
|
||||
len,
|
||||
len_cached,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Okm<'_, Algorithm>> for Prk {
|
||||
fn from(okm: Okm<Algorithm>) -> Self {
|
||||
Self(hmac::Key::from(Okm {
|
||||
prk: okm.prk,
|
||||
info: okm.info,
|
||||
len: okm.len().0,
|
||||
len_cached: okm.len_cached,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/// An HKDF OKM (Output Keying Material)
|
||||
///
|
||||
/// Intentionally not `Clone` or `Copy` as an OKM is generally only safe to
|
||||
/// use once.
|
||||
#[derive(Debug)]
|
||||
pub struct Okm<'a, L: KeyType> {
|
||||
prk: &'a Prk,
|
||||
info: &'a [&'a [u8]],
|
||||
len: L,
|
||||
len_cached: usize,
|
||||
}
|
||||
|
||||
impl<L: KeyType> Okm<'_, L> {
|
||||
/// The `OkmLength` given to `Prk::expand()`.
|
||||
#[inline]
|
||||
pub fn len(&self) -> &L {
|
||||
&self.len
|
||||
}
|
||||
|
||||
/// Fills `out` with the output of the HKDF-Expand operation for the given
|
||||
/// inputs.
|
||||
///
|
||||
/// Fails if (and only if) the requested output length is larger than 255
|
||||
/// times the size of the digest algorithm's output. (This is the limit
|
||||
/// imposed by the HKDF specification due to the way HKDF's counter is
|
||||
/// constructed.)
|
||||
#[inline]
|
||||
pub fn fill(self, out: &mut [u8]) -> Result<(), error::Unspecified> {
|
||||
fill_okm(self.prk, self.info, out, self.len_cached)
|
||||
}
|
||||
}
|
||||
|
||||
fn fill_okm(
|
||||
prk: &Prk,
|
||||
info: &[&[u8]],
|
||||
out: &mut [u8],
|
||||
len: usize,
|
||||
) -> Result<(), error::Unspecified> {
|
||||
if out.len() != len {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
let digest_alg = prk.0.algorithm().digest_algorithm();
|
||||
assert!(digest_alg.block_len >= digest_alg.output_len);
|
||||
|
||||
let mut ctx = hmac::Context::with_key(&prk.0);
|
||||
|
||||
let mut n = 1u8;
|
||||
let mut out = out;
|
||||
loop {
|
||||
for info in info {
|
||||
ctx.update(info);
|
||||
}
|
||||
ctx.update(&[n]);
|
||||
|
||||
let t = ctx.sign();
|
||||
let t = t.as_ref();
|
||||
|
||||
// Append `t` to the output.
|
||||
out = if out.len() < digest_alg.output_len {
|
||||
let len = out.len();
|
||||
out.copy_from_slice(&t[..len]);
|
||||
&mut []
|
||||
} else {
|
||||
let (this_chunk, rest) = out.split_at_mut(digest_alg.output_len);
|
||||
this_chunk.copy_from_slice(t);
|
||||
rest
|
||||
};
|
||||
|
||||
if out.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
ctx = hmac::Context::with_key(&prk.0);
|
||||
ctx.update(t);
|
||||
n = n.checked_add(1).unwrap();
|
||||
}
|
||||
}
|
||||
385
zeroidc/vendor/ring/src/hmac.rs
vendored
Normal file
385
zeroidc/vendor/ring/src/hmac.rs
vendored
Normal file
@@ -0,0 +1,385 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! HMAC is specified in [RFC 2104].
|
||||
//!
|
||||
//! After a `Key` is constructed, it can be used for multiple signing or
|
||||
//! verification operations. Separating the construction of the key from the
|
||||
//! rest of the HMAC operation allows the per-key precomputation to be done
|
||||
//! only once, instead of it being done in every HMAC operation.
|
||||
//!
|
||||
//! Frequently all the data to be signed in a message is available in a single
|
||||
//! contiguous piece. In that case, the module-level `sign` function can be
|
||||
//! used. Otherwise, if the input is in multiple parts, `Context` should be
|
||||
//! used.
|
||||
//!
|
||||
//! # Examples:
|
||||
//!
|
||||
//! ## Signing a value and verifying it wasn't tampered with
|
||||
//!
|
||||
//! ```
|
||||
//! use ring::{hmac, rand};
|
||||
//!
|
||||
//! let rng = rand::SystemRandom::new();
|
||||
//! let key = hmac::Key::generate(hmac::HMAC_SHA256, &rng)?;
|
||||
//!
|
||||
//! let msg = "hello, world";
|
||||
//!
|
||||
//! let tag = hmac::sign(&key, msg.as_bytes());
|
||||
//!
|
||||
//! // [We give access to the message to an untrusted party, and they give it
|
||||
//! // back to us. We need to verify they didn't tamper with it.]
|
||||
//!
|
||||
//! hmac::verify(&key, msg.as_bytes(), tag.as_ref())?;
|
||||
//!
|
||||
//! # Ok::<(), ring::error::Unspecified>(())
|
||||
//! ```
|
||||
//!
|
||||
//! ## Using the one-shot API:
|
||||
//!
|
||||
//! ```
|
||||
//! use ring::{digest, hmac, rand};
|
||||
//! use ring::rand::SecureRandom;
|
||||
//!
|
||||
//! let msg = "hello, world";
|
||||
//!
|
||||
//! // The sender generates a secure key value and signs the message with it.
|
||||
//! // Note that in a real protocol, a key agreement protocol would be used to
|
||||
//! // derive `key_value`.
|
||||
//! let rng = rand::SystemRandom::new();
|
||||
//! let key_value: [u8; digest::SHA256_OUTPUT_LEN] = rand::generate(&rng)?.expose();
|
||||
//!
|
||||
//! let s_key = hmac::Key::new(hmac::HMAC_SHA256, key_value.as_ref());
|
||||
//! let tag = hmac::sign(&s_key, msg.as_bytes());
|
||||
//!
|
||||
//! // The receiver (somehow!) knows the key value, and uses it to verify the
|
||||
//! // integrity of the message.
|
||||
//! let v_key = hmac::Key::new(hmac::HMAC_SHA256, key_value.as_ref());
|
||||
//! hmac::verify(&v_key, msg.as_bytes(), tag.as_ref())?;
|
||||
//!
|
||||
//! # Ok::<(), ring::error::Unspecified>(())
|
||||
//! ```
|
||||
//!
|
||||
//! ## Using the multi-part API:
|
||||
//! ```
|
||||
//! use ring::{digest, hmac, rand};
|
||||
//! use ring::rand::SecureRandom;
|
||||
//!
|
||||
//! let parts = ["hello", ", ", "world"];
|
||||
//!
|
||||
//! // The sender generates a secure key value and signs the message with it.
|
||||
//! // Note that in a real protocol, a key agreement protocol would be used to
|
||||
//! // derive `key_value`.
|
||||
//! let rng = rand::SystemRandom::new();
|
||||
//! let mut key_value: [u8; digest::SHA384_OUTPUT_LEN] = rand::generate(&rng)?.expose();
|
||||
//!
|
||||
//! let s_key = hmac::Key::new(hmac::HMAC_SHA384, key_value.as_ref());
|
||||
//! let mut s_ctx = hmac::Context::with_key(&s_key);
|
||||
//! for part in &parts {
|
||||
//! s_ctx.update(part.as_bytes());
|
||||
//! }
|
||||
//! let tag = s_ctx.sign();
|
||||
//!
|
||||
//! // The receiver (somehow!) knows the key value, and uses it to verify the
|
||||
//! // integrity of the message.
|
||||
//! let v_key = hmac::Key::new(hmac::HMAC_SHA384, key_value.as_ref());
|
||||
//! let mut msg = Vec::<u8>::new();
|
||||
//! for part in &parts {
|
||||
//! msg.extend(part.as_bytes());
|
||||
//! }
|
||||
//! hmac::verify(&v_key, &msg.as_ref(), tag.as_ref())?;
|
||||
//!
|
||||
//! # Ok::<(), ring::error::Unspecified>(())
|
||||
//! ```
|
||||
//!
|
||||
//! [RFC 2104]: https://tools.ietf.org/html/rfc2104
|
||||
//! [code for `ring::pbkdf2`]:
|
||||
//! https://github.com/briansmith/ring/blob/main/src/pbkdf2.rs
|
||||
//! [code for `ring::hkdf`]:
|
||||
//! https://github.com/briansmith/ring/blob/main/src/hkdf.rs
|
||||
|
||||
use crate::{constant_time, digest, error, hkdf, rand};
|
||||
|
||||
/// An HMAC algorithm.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Algorithm(&'static digest::Algorithm);
|
||||
|
||||
impl Algorithm {
|
||||
/// The digest algorithm this HMAC algorithm is based on.
|
||||
#[inline]
|
||||
pub fn digest_algorithm(&self) -> &'static digest::Algorithm {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// HMAC using SHA-1. Obsolete.
|
||||
pub static HMAC_SHA1_FOR_LEGACY_USE_ONLY: Algorithm = Algorithm(&digest::SHA1_FOR_LEGACY_USE_ONLY);
|
||||
|
||||
/// HMAC using SHA-256.
|
||||
pub static HMAC_SHA256: Algorithm = Algorithm(&digest::SHA256);
|
||||
|
||||
/// HMAC using SHA-384.
|
||||
pub static HMAC_SHA384: Algorithm = Algorithm(&digest::SHA384);
|
||||
|
||||
/// HMAC using SHA-512.
|
||||
pub static HMAC_SHA512: Algorithm = Algorithm(&digest::SHA512);
|
||||
|
||||
/// A deprecated alias for `Tag`.
|
||||
#[deprecated(note = "`Signature` was renamed to `Tag`. This alias will be removed soon.")]
|
||||
pub type Signature = Tag;
|
||||
|
||||
/// An HMAC tag.
|
||||
///
|
||||
/// For a given tag `t`, use `t.as_ref()` to get the tag value as a byte slice.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Tag(digest::Digest);
|
||||
|
||||
impl AsRef<[u8]> for Tag {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
/// A key to use for HMAC signing.
|
||||
#[derive(Clone)]
|
||||
pub struct Key {
|
||||
inner: digest::BlockContext,
|
||||
outer: digest::BlockContext,
|
||||
}
|
||||
|
||||
/// `hmac::SigningKey` was renamed to `hmac::Key`.
|
||||
#[deprecated(note = "Renamed to `hmac::Key`.")]
|
||||
pub type SigningKey = Key;
|
||||
|
||||
/// `hmac::VerificationKey` was merged into `hmac::Key`.
|
||||
#[deprecated(
|
||||
note = "The distinction between verification & signing keys was removed. Use `hmac::Key`."
|
||||
)]
|
||||
pub type VerificationKey = Key;
|
||||
|
||||
impl core::fmt::Debug for Key {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
f.debug_struct("Key")
|
||||
.field("algorithm", self.algorithm().digest_algorithm())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Key {
|
||||
/// Generate an HMAC signing key using the given digest algorithm with a
|
||||
/// random value generated from `rng`.
|
||||
///
|
||||
/// The key will be `digest_alg.output_len` bytes long, based on the
|
||||
/// recommendation in [RFC 2104 Section 3].
|
||||
///
|
||||
/// [RFC 2104 Section 3]: https://tools.ietf.org/html/rfc2104#section-3
|
||||
pub fn generate(
|
||||
algorithm: Algorithm,
|
||||
rng: &dyn rand::SecureRandom,
|
||||
) -> Result<Self, error::Unspecified> {
|
||||
Self::construct(algorithm, |buf| rng.fill(buf))
|
||||
}
|
||||
|
||||
fn construct<F>(algorithm: Algorithm, fill: F) -> Result<Self, error::Unspecified>
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> Result<(), error::Unspecified>,
|
||||
{
|
||||
let mut key_bytes = [0; digest::MAX_OUTPUT_LEN];
|
||||
let key_bytes = &mut key_bytes[..algorithm.0.output_len];
|
||||
fill(key_bytes)?;
|
||||
Ok(Self::new(algorithm, key_bytes))
|
||||
}
|
||||
|
||||
/// Construct an HMAC signing key using the given digest algorithm and key
|
||||
/// value.
|
||||
///
|
||||
/// `key_value` should be a value generated using a secure random number
|
||||
/// generator (e.g. the `key_value` output by
|
||||
/// `SealingKey::generate_serializable()`) or derived from a random key by
|
||||
/// a key derivation function (e.g. `ring::hkdf`). In particular,
|
||||
/// `key_value` shouldn't be a password.
|
||||
///
|
||||
/// As specified in RFC 2104, if `key_value` is shorter than the digest
|
||||
/// algorithm's block length (as returned by `digest::Algorithm::block_len`,
|
||||
/// not the digest length returned by `digest::Algorithm::output_len`) then
|
||||
/// it will be padded with zeros. Similarly, if it is longer than the block
|
||||
/// length then it will be compressed using the digest algorithm.
|
||||
///
|
||||
/// You should not use keys larger than the `digest_alg.block_len` because
|
||||
/// the truncation described above reduces their strength to only
|
||||
/// `digest_alg.output_len * 8` bits. Support for such keys is likely to be
|
||||
/// removed in a future version of *ring*.
|
||||
pub fn new(algorithm: Algorithm, key_value: &[u8]) -> Self {
|
||||
let digest_alg = algorithm.0;
|
||||
let mut key = Self {
|
||||
inner: digest::BlockContext::new(digest_alg),
|
||||
outer: digest::BlockContext::new(digest_alg),
|
||||
};
|
||||
|
||||
let key_hash;
|
||||
let key_value = if key_value.len() <= digest_alg.block_len {
|
||||
key_value
|
||||
} else {
|
||||
key_hash = digest::digest(digest_alg, key_value);
|
||||
key_hash.as_ref()
|
||||
};
|
||||
|
||||
const IPAD: u8 = 0x36;
|
||||
|
||||
let mut padded_key = [IPAD; digest::MAX_BLOCK_LEN];
|
||||
let padded_key = &mut padded_key[..digest_alg.block_len];
|
||||
|
||||
// If the key is shorter than one block then we're supposed to act like
|
||||
// it is padded with zero bytes up to the block length. `x ^ 0 == x` so
|
||||
// we can just leave the trailing bytes of `padded_key` untouched.
|
||||
for (padded_key, key_value) in padded_key.iter_mut().zip(key_value.iter()) {
|
||||
*padded_key ^= *key_value;
|
||||
}
|
||||
key.inner.update(&padded_key);
|
||||
|
||||
const OPAD: u8 = 0x5C;
|
||||
|
||||
// Remove the `IPAD` masking, leaving the unmasked padded key, then
|
||||
// mask with `OPAD`, all in one step.
|
||||
for b in padded_key.iter_mut() {
|
||||
*b ^= IPAD ^ OPAD;
|
||||
}
|
||||
key.outer.update(&padded_key);
|
||||
|
||||
key
|
||||
}
|
||||
|
||||
/// The digest algorithm for the key.
|
||||
#[inline]
|
||||
pub fn algorithm(&self) -> Algorithm {
|
||||
Algorithm(self.inner.algorithm)
|
||||
}
|
||||
}
|
||||
|
||||
impl hkdf::KeyType for Algorithm {
|
||||
fn len(&self) -> usize {
|
||||
self.digest_algorithm().output_len
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hkdf::Okm<'_, Algorithm>> for Key {
|
||||
fn from(okm: hkdf::Okm<Algorithm>) -> Self {
|
||||
Key::construct(*okm.len(), |buf| okm.fill(buf)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// A context for multi-step (Init-Update-Finish) HMAC signing.
|
||||
///
|
||||
/// Use `sign` for single-step HMAC signing.
|
||||
#[derive(Clone)]
|
||||
pub struct Context {
|
||||
inner: digest::Context,
|
||||
outer: digest::BlockContext,
|
||||
}
|
||||
|
||||
/// `hmac::SigningContext` was renamed to `hmac::Context`.
|
||||
#[deprecated(note = "Renamed to `hmac::Context`.")]
|
||||
pub type SigningContext = Context;
|
||||
|
||||
impl core::fmt::Debug for Context {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
|
||||
f.debug_struct("Context")
|
||||
.field("algorithm", self.inner.algorithm())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Constructs a new HMAC signing context using the given digest algorithm
|
||||
/// and key.
|
||||
pub fn with_key(signing_key: &Key) -> Self {
|
||||
Self {
|
||||
inner: digest::Context::clone_from(&signing_key.inner),
|
||||
outer: signing_key.outer.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the HMAC with all the data in `data`. `update` may be called
|
||||
/// zero or more times until `finish` is called.
|
||||
pub fn update(&mut self, data: &[u8]) {
|
||||
self.inner.update(data);
|
||||
}
|
||||
|
||||
/// Finalizes the HMAC calculation and returns the HMAC value. `sign`
|
||||
/// consumes the context so it cannot be (mis-)used after `sign` has been
|
||||
/// called.
|
||||
///
|
||||
/// It is generally not safe to implement HMAC verification by comparing
|
||||
/// the return value of `sign` to a tag. Use `verify` for verification
|
||||
/// instead.
|
||||
pub fn sign(self) -> Tag {
|
||||
let algorithm = self.inner.algorithm();
|
||||
let mut pending = [0u8; digest::MAX_BLOCK_LEN];
|
||||
let pending = &mut pending[..algorithm.block_len];
|
||||
let num_pending = algorithm.output_len;
|
||||
pending[..num_pending].copy_from_slice(self.inner.finish().as_ref());
|
||||
Tag(self.outer.finish(pending, num_pending))
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the HMAC of `data` using the key `key` in one step.
|
||||
///
|
||||
/// Use `Context` to calculate HMACs where the input is in multiple parts.
|
||||
///
|
||||
/// It is generally not safe to implement HMAC verification by comparing the
|
||||
/// return value of `sign` to a tag. Use `verify` for verification instead.
|
||||
pub fn sign(key: &Key, data: &[u8]) -> Tag {
|
||||
let mut ctx = Context::with_key(key);
|
||||
ctx.update(data);
|
||||
ctx.sign()
|
||||
}
|
||||
|
||||
/// Calculates the HMAC of `data` using the signing key `key`, and verifies
|
||||
/// whether the resultant value equals `tag`, in one step.
|
||||
///
|
||||
/// This is logically equivalent to, but more efficient than, constructing a
|
||||
/// `Key` with the same value as `key` and then using `verify`.
|
||||
///
|
||||
/// The verification will be done in constant time to prevent timing attacks.
|
||||
pub fn verify(key: &Key, data: &[u8], tag: &[u8]) -> Result<(), error::Unspecified> {
|
||||
constant_time::verify_slices_are_equal(sign(key, data).as_ref(), tag)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{hmac, rand};
|
||||
|
||||
// Make sure that `Key::generate` and `verify_with_own_key` aren't
|
||||
// completely wacky.
|
||||
#[test]
|
||||
pub fn hmac_signing_key_coverage() {
|
||||
let rng = rand::SystemRandom::new();
|
||||
|
||||
const HELLO_WORLD_GOOD: &[u8] = b"hello, world";
|
||||
const HELLO_WORLD_BAD: &[u8] = b"hello, worle";
|
||||
|
||||
for algorithm in &[
|
||||
hmac::HMAC_SHA1_FOR_LEGACY_USE_ONLY,
|
||||
hmac::HMAC_SHA256,
|
||||
hmac::HMAC_SHA384,
|
||||
hmac::HMAC_SHA512,
|
||||
] {
|
||||
let key = hmac::Key::generate(*algorithm, &rng).unwrap();
|
||||
let tag = hmac::sign(&key, HELLO_WORLD_GOOD);
|
||||
assert!(hmac::verify(&key, HELLO_WORLD_GOOD, tag.as_ref()).is_ok());
|
||||
assert!(hmac::verify(&key, HELLO_WORLD_BAD, tag.as_ref()).is_err())
|
||||
}
|
||||
}
|
||||
}
|
||||
11
zeroidc/vendor/ring/src/hmac_generate_serializable_tests.txt
vendored
Normal file
11
zeroidc/vendor/ring/src/hmac_generate_serializable_tests.txt
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
HMAC = SHA1
|
||||
Key = 000102030405060708090a0b0c0d0e0f10111213
|
||||
|
||||
HMAC = SHA256
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
|
||||
HMAC = SHA384
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
|
||||
|
||||
HMAC = SHA512
|
||||
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
|
||||
28
zeroidc/vendor/ring/src/io.rs
vendored
Normal file
28
zeroidc/vendor/ring/src/io.rs
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Serialization and deserialization.
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod der;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
mod writer;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub(crate) mod der_writer;
|
||||
|
||||
pub(crate) mod positive;
|
||||
|
||||
pub use self::positive::Positive;
|
||||
311
zeroidc/vendor/ring/src/io/der.rs
vendored
Normal file
311
zeroidc/vendor/ring/src/io/der.rs
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
// Copyright 2015 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Building blocks for parsing DER-encoded ASN.1 structures.
|
||||
//!
|
||||
//! This module contains the foundational parts of an ASN.1 DER parser.
|
||||
|
||||
use super::Positive;
|
||||
use crate::error;
|
||||
|
||||
pub const CONSTRUCTED: u8 = 1 << 5;
|
||||
pub const CONTEXT_SPECIFIC: u8 = 2 << 6;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum Tag {
|
||||
Boolean = 0x01,
|
||||
Integer = 0x02,
|
||||
BitString = 0x03,
|
||||
OctetString = 0x04,
|
||||
Null = 0x05,
|
||||
OID = 0x06,
|
||||
Sequence = CONSTRUCTED | 0x10, // 0x30
|
||||
UTCTime = 0x17,
|
||||
GeneralizedTime = 0x18,
|
||||
|
||||
ContextSpecificConstructed0 = CONTEXT_SPECIFIC | CONSTRUCTED | 0,
|
||||
ContextSpecificConstructed1 = CONTEXT_SPECIFIC | CONSTRUCTED | 1,
|
||||
ContextSpecificConstructed3 = CONTEXT_SPECIFIC | CONSTRUCTED | 3,
|
||||
}
|
||||
|
||||
impl From<Tag> for usize {
|
||||
fn from(tag: Tag) -> Self {
|
||||
tag as Self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Tag> for u8 {
|
||||
fn from(tag: Tag) -> Self {
|
||||
tag as Self
|
||||
} // XXX: narrowing conversion.
|
||||
}
|
||||
|
||||
pub fn expect_tag_and_get_value<'a>(
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
tag: Tag,
|
||||
) -> Result<untrusted::Input<'a>, error::Unspecified> {
|
||||
let (actual_tag, inner) = read_tag_and_get_value(input)?;
|
||||
if usize::from(tag) != usize::from(actual_tag) {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
Ok(inner)
|
||||
}
|
||||
|
||||
pub fn read_tag_and_get_value<'a>(
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
) -> Result<(u8, untrusted::Input<'a>), error::Unspecified> {
|
||||
let tag = input.read_byte()?;
|
||||
if (tag & 0x1F) == 0x1F {
|
||||
return Err(error::Unspecified); // High tag number form is not allowed.
|
||||
}
|
||||
|
||||
// If the high order bit of the first byte is set to zero then the length
|
||||
// is encoded in the seven remaining bits of that byte. Otherwise, those
|
||||
// seven bits represent the number of bytes used to encode the length.
|
||||
let length = match input.read_byte()? {
|
||||
n if (n & 0x80) == 0 => usize::from(n),
|
||||
0x81 => {
|
||||
let second_byte = input.read_byte()?;
|
||||
if second_byte < 128 {
|
||||
return Err(error::Unspecified); // Not the canonical encoding.
|
||||
}
|
||||
usize::from(second_byte)
|
||||
}
|
||||
0x82 => {
|
||||
let second_byte = usize::from(input.read_byte()?);
|
||||
let third_byte = usize::from(input.read_byte()?);
|
||||
let combined = (second_byte << 8) | third_byte;
|
||||
if combined < 256 {
|
||||
return Err(error::Unspecified); // Not the canonical encoding.
|
||||
}
|
||||
combined
|
||||
}
|
||||
_ => {
|
||||
return Err(error::Unspecified); // We don't support longer lengths.
|
||||
}
|
||||
};
|
||||
|
||||
let inner = input.read_bytes(length)?;
|
||||
Ok((tag, inner))
|
||||
}
|
||||
|
||||
pub fn bit_string_with_no_unused_bits<'a>(
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
) -> Result<untrusted::Input<'a>, error::Unspecified> {
|
||||
nested(input, Tag::BitString, error::Unspecified, |value| {
|
||||
let unused_bits_at_end = value.read_byte().map_err(|_| error::Unspecified)?;
|
||||
if unused_bits_at_end != 0 {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
Ok(value.read_bytes_to_end())
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: investigate taking decoder as a reference to reduce generated code
|
||||
// size.
|
||||
pub fn nested<'a, F, R, E: Copy>(
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
tag: Tag,
|
||||
error: E,
|
||||
decoder: F,
|
||||
) -> Result<R, E>
|
||||
where
|
||||
F: FnOnce(&mut untrusted::Reader<'a>) -> Result<R, E>,
|
||||
{
|
||||
let inner = expect_tag_and_get_value(input, tag).map_err(|_| error)?;
|
||||
inner.read_all(error, decoder)
|
||||
}
|
||||
|
||||
fn nonnegative_integer<'a>(
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
min_value: u8,
|
||||
) -> Result<untrusted::Input<'a>, error::Unspecified> {
|
||||
// Verify that |input|, which has had any leading zero stripped off, is the
|
||||
// encoding of a value of at least |min_value|.
|
||||
fn check_minimum(input: untrusted::Input, min_value: u8) -> Result<(), error::Unspecified> {
|
||||
input.read_all(error::Unspecified, |input| {
|
||||
let first_byte = input.read_byte()?;
|
||||
if input.at_end() && first_byte < min_value {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
let _ = input.read_bytes_to_end();
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
let value = expect_tag_and_get_value(input, Tag::Integer)?;
|
||||
|
||||
value.read_all(error::Unspecified, |input| {
|
||||
// Empty encodings are not allowed.
|
||||
let first_byte = input.read_byte()?;
|
||||
|
||||
if first_byte == 0 {
|
||||
if input.at_end() {
|
||||
// |value| is the legal encoding of zero.
|
||||
if min_value > 0 {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
return Ok(value);
|
||||
}
|
||||
|
||||
let r = input.read_bytes_to_end();
|
||||
r.read_all(error::Unspecified, |input| {
|
||||
let second_byte = input.read_byte()?;
|
||||
if (second_byte & 0x80) == 0 {
|
||||
// A leading zero is only allowed when the value's high bit
|
||||
// is set.
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
let _ = input.read_bytes_to_end();
|
||||
Ok(())
|
||||
})?;
|
||||
check_minimum(r, min_value)?;
|
||||
return Ok(r);
|
||||
}
|
||||
|
||||
// Negative values are not allowed.
|
||||
if (first_byte & 0x80) != 0 {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
let _ = input.read_bytes_to_end();
|
||||
check_minimum(value, min_value)?;
|
||||
Ok(value)
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse as integer with a value in the in the range [0, 255], returning its
|
||||
/// numeric value. This is typically used for parsing version numbers.
|
||||
#[inline]
|
||||
pub fn small_nonnegative_integer(input: &mut untrusted::Reader) -> Result<u8, error::Unspecified> {
|
||||
let value = nonnegative_integer(input, 0)?;
|
||||
value.read_all(error::Unspecified, |input| {
|
||||
let r = input.read_byte()?;
|
||||
Ok(r)
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses a positive DER integer, returning the big-endian-encoded value,
|
||||
/// sans any leading zero byte.
|
||||
pub fn positive_integer<'a>(
|
||||
input: &mut untrusted::Reader<'a>,
|
||||
) -> Result<Positive<'a>, error::Unspecified> {
|
||||
Ok(Positive::new_non_empty_without_leading_zeros(
|
||||
nonnegative_integer(input, 1)?,
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::error;
|
||||
|
||||
fn with_good_i<F, R>(value: &[u8], f: F)
|
||||
where
|
||||
F: FnOnce(&mut untrusted::Reader) -> Result<R, error::Unspecified>,
|
||||
{
|
||||
let r = untrusted::Input::from(value).read_all(error::Unspecified, f);
|
||||
assert!(r.is_ok());
|
||||
}
|
||||
|
||||
fn with_bad_i<F, R>(value: &[u8], f: F)
|
||||
where
|
||||
F: FnOnce(&mut untrusted::Reader) -> Result<R, error::Unspecified>,
|
||||
{
|
||||
let r = untrusted::Input::from(value).read_all(error::Unspecified, f);
|
||||
assert!(r.is_err());
|
||||
}
|
||||
|
||||
static ZERO_INTEGER: &[u8] = &[0x02, 0x01, 0x00];
|
||||
|
||||
static GOOD_POSITIVE_INTEGERS: &[(&[u8], u8)] = &[
|
||||
(&[0x02, 0x01, 0x01], 0x01),
|
||||
(&[0x02, 0x01, 0x02], 0x02),
|
||||
(&[0x02, 0x01, 0x7e], 0x7e),
|
||||
(&[0x02, 0x01, 0x7f], 0x7f),
|
||||
// Values that need to have an 0x00 prefix to disambiguate them from
|
||||
// them from negative values.
|
||||
(&[0x02, 0x02, 0x00, 0x80], 0x80),
|
||||
(&[0x02, 0x02, 0x00, 0x81], 0x81),
|
||||
(&[0x02, 0x02, 0x00, 0xfe], 0xfe),
|
||||
(&[0x02, 0x02, 0x00, 0xff], 0xff),
|
||||
];
|
||||
|
||||
static BAD_NONNEGATIVE_INTEGERS: &[&[u8]] = &[
|
||||
&[], // At end of input
|
||||
&[0x02], // Tag only
|
||||
&[0x02, 0x00], // Empty value
|
||||
// Length mismatch
|
||||
&[0x02, 0x00, 0x01],
|
||||
&[0x02, 0x01],
|
||||
&[0x02, 0x01, 0x00, 0x01],
|
||||
&[0x02, 0x01, 0x01, 0x00], // Would be valid if last byte is ignored.
|
||||
&[0x02, 0x02, 0x01],
|
||||
// Negative values
|
||||
&[0x02, 0x01, 0x80],
|
||||
&[0x02, 0x01, 0xfe],
|
||||
&[0x02, 0x01, 0xff],
|
||||
// Values that have an unnecessary leading 0x00
|
||||
&[0x02, 0x02, 0x00, 0x00],
|
||||
&[0x02, 0x02, 0x00, 0x01],
|
||||
&[0x02, 0x02, 0x00, 0x02],
|
||||
&[0x02, 0x02, 0x00, 0x7e],
|
||||
&[0x02, 0x02, 0x00, 0x7f],
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_small_nonnegative_integer() {
|
||||
with_good_i(ZERO_INTEGER, |input| {
|
||||
assert_eq!(small_nonnegative_integer(input)?, 0x00);
|
||||
Ok(())
|
||||
});
|
||||
for &(test_in, test_out) in GOOD_POSITIVE_INTEGERS.iter() {
|
||||
with_good_i(test_in, |input| {
|
||||
assert_eq!(small_nonnegative_integer(input)?, test_out);
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
for &test_in in BAD_NONNEGATIVE_INTEGERS.iter() {
|
||||
with_bad_i(test_in, |input| {
|
||||
let _ = small_nonnegative_integer(input)?;
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_positive_integer() {
|
||||
with_bad_i(ZERO_INTEGER, |input| {
|
||||
let _ = positive_integer(input)?;
|
||||
Ok(())
|
||||
});
|
||||
for &(test_in, test_out) in GOOD_POSITIVE_INTEGERS.iter() {
|
||||
with_good_i(test_in, |input| {
|
||||
let test_out = [test_out];
|
||||
assert_eq!(
|
||||
positive_integer(input)?.big_endian_without_leading_zero_as_input(),
|
||||
untrusted::Input::from(&test_out[..])
|
||||
);
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
for &test_in in BAD_NONNEGATIVE_INTEGERS.iter() {
|
||||
with_bad_i(test_in, |input| {
|
||||
let _ = positive_integer(input)?;
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
67
zeroidc/vendor/ring/src/io/der_writer.rs
vendored
Normal file
67
zeroidc/vendor/ring/src/io/der_writer.rs
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use super::{der::*, writer::*, *};
|
||||
use alloc::boxed::Box;
|
||||
|
||||
pub(crate) fn write_positive_integer(output: &mut dyn Accumulator, value: &Positive) {
|
||||
let first_byte = value.first_byte();
|
||||
let value = value.big_endian_without_leading_zero_as_input();
|
||||
write_tlv(output, Tag::Integer, |output| {
|
||||
if (first_byte & 0x80) != 0 {
|
||||
output.write_byte(0); // Disambiguate negative number.
|
||||
}
|
||||
write_copy(output, value)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn write_all(tag: Tag, write_value: &dyn Fn(&mut dyn Accumulator)) -> Box<[u8]> {
|
||||
let length = {
|
||||
let mut length = LengthMeasurement::zero();
|
||||
write_tlv(&mut length, tag, write_value);
|
||||
length
|
||||
};
|
||||
|
||||
let mut output = Writer::with_capacity(length);
|
||||
write_tlv(&mut output, tag, write_value);
|
||||
|
||||
output.into()
|
||||
}
|
||||
|
||||
fn write_tlv<F>(output: &mut dyn Accumulator, tag: Tag, write_value: F)
|
||||
where
|
||||
F: Fn(&mut dyn Accumulator),
|
||||
{
|
||||
let length: usize = {
|
||||
let mut length = LengthMeasurement::zero();
|
||||
write_value(&mut length);
|
||||
length.into()
|
||||
};
|
||||
|
||||
output.write_byte(tag as u8);
|
||||
if length < 0x80 {
|
||||
output.write_byte(length as u8);
|
||||
} else if length < 0x1_00 {
|
||||
output.write_byte(0x81);
|
||||
output.write_byte(length as u8);
|
||||
} else if length < 0x1_00_00 {
|
||||
output.write_byte(0x82);
|
||||
output.write_byte((length / 0x1_00) as u8);
|
||||
output.write_byte(length as u8);
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
write_value(output);
|
||||
}
|
||||
53
zeroidc/vendor/ring/src/io/positive.rs
vendored
Normal file
53
zeroidc/vendor/ring/src/io/positive.rs
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Serialization and deserialization.
|
||||
|
||||
/// A serialized positive integer.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Positive<'a>(untrusted::Input<'a>);
|
||||
|
||||
impl<'a> Positive<'a> {
|
||||
#[inline]
|
||||
pub(crate) fn new_non_empty_without_leading_zeros(input: untrusted::Input<'a>) -> Self {
|
||||
debug_assert!(!input.is_empty());
|
||||
debug_assert!(input.len() == 1 || input.as_slice_less_safe()[0] != 0);
|
||||
Self(input)
|
||||
}
|
||||
|
||||
/// Returns the value, ordered from significant byte to least significant
|
||||
/// byte, without any leading zeros. The result is guaranteed to be
|
||||
/// non-empty.
|
||||
#[inline]
|
||||
pub fn big_endian_without_leading_zero(&self) -> &'a [u8] {
|
||||
self.big_endian_without_leading_zero_as_input()
|
||||
.as_slice_less_safe()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn big_endian_without_leading_zero_as_input(&self) -> untrusted::Input<'a> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Positive<'_> {
|
||||
/// Returns the first byte.
|
||||
///
|
||||
/// Will not panic because the value is guaranteed to have at least one
|
||||
/// byte.
|
||||
pub fn first_byte(&self) -> u8 {
|
||||
// This won't panic because
|
||||
self.0.as_slice_less_safe()[0]
|
||||
}
|
||||
}
|
||||
79
zeroidc/vendor/ring/src/io/writer.rs
vendored
Normal file
79
zeroidc/vendor/ring/src/io/writer.rs
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2018 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
|
||||
pub trait Accumulator {
|
||||
fn write_byte(&mut self, value: u8);
|
||||
fn write_bytes(&mut self, value: &[u8]);
|
||||
}
|
||||
|
||||
pub(super) struct LengthMeasurement {
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl Into<usize> for LengthMeasurement {
|
||||
fn into(self) -> usize {
|
||||
self.len
|
||||
}
|
||||
}
|
||||
|
||||
impl LengthMeasurement {
|
||||
pub fn zero() -> Self {
|
||||
Self { len: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Accumulator for LengthMeasurement {
|
||||
fn write_byte(&mut self, _value: u8) {
|
||||
self.len += 1;
|
||||
}
|
||||
fn write_bytes(&mut self, value: &[u8]) {
|
||||
self.len += value.len();
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Writer {
|
||||
bytes: Vec<u8>,
|
||||
requested_capacity: usize,
|
||||
}
|
||||
|
||||
impl Writer {
|
||||
pub(super) fn with_capacity(capacity: LengthMeasurement) -> Self {
|
||||
Self {
|
||||
bytes: Vec::with_capacity(capacity.len),
|
||||
requested_capacity: capacity.len,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Box<[u8]>> for Writer {
|
||||
fn into(self) -> Box<[u8]> {
|
||||
assert_eq!(self.requested_capacity, self.bytes.len());
|
||||
self.bytes.into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl Accumulator for Writer {
|
||||
fn write_byte(&mut self, value: u8) {
|
||||
self.bytes.push(value);
|
||||
}
|
||||
fn write_bytes(&mut self, value: &[u8]) {
|
||||
self.bytes.extend(value);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_copy(accumulator: &mut dyn Accumulator, to_copy: untrusted::Input) {
|
||||
accumulator.write_bytes(to_copy.as_slice_less_safe())
|
||||
}
|
||||
135
zeroidc/vendor/ring/src/lib.rs
vendored
Normal file
135
zeroidc/vendor/ring/src/lib.rs
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright 2015-2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Safe, fast, small crypto using Rust with BoringSSL's cryptography
|
||||
//! primitives.
|
||||
//!
|
||||
//! # Feature Flags
|
||||
//!
|
||||
//! <table>
|
||||
//! <tr><th>Feature
|
||||
//! <th>Description
|
||||
//! <tr><td><code>alloc (default)</code>
|
||||
//! <td>Enable features that require use of the heap, RSA in particular.
|
||||
//! <tr><td><code>dev_urandom_fallback (default)</code>
|
||||
//! <td>This is only applicable to Linux. On Linux, by default,
|
||||
//! <code>ring::rand::SystemRandom</code> will fall back to reading
|
||||
//! from <code>/dev/urandom</code> if the <code>getrandom()</code>
|
||||
//! syscall isn't supported at runtime. When the
|
||||
//! <code>dev_urandom_fallback</code> feature is disabled, such
|
||||
//! fallbacks will not occur. See the documentation for
|
||||
//! <code>rand::SystemRandom</code> for more details.
|
||||
//! <tr><td><code>std</code>
|
||||
//! <td>Enable features that use libstd, in particular
|
||||
//! <code>std::error::Error</code> integration. Implies `alloc`.
|
||||
//! <tr><td><code>wasm32_c</code>
|
||||
//! <td>Enables features that require a C compiler on wasm32 targets, such as
|
||||
//! the <code>constant_time</code> module, HMAC verification, and PBKDF2
|
||||
//! verification. Without this feature, only a subset of functionality
|
||||
//! is provided to wasm32 targets so that a C compiler isn't needed. A
|
||||
//! typical invocation would be:
|
||||
//! <code>TARGET_CC=clang-10 TARGET_AR=llvm-ar-10 cargo test --target=wasm32-unknown-unknown --features=wasm32_c</code>
|
||||
//! with <code>llvm-ar-10</code> and <code>clang-10</code> in <code>$PATH</code>.
|
||||
//! (Going forward more functionality should be enabled by default, without
|
||||
//! requiring these hacks, and without requiring a C compiler.)
|
||||
//! </table>
|
||||
|
||||
#![doc(html_root_url = "https://briansmith.org/rustdoc/")]
|
||||
#![allow(
|
||||
clippy::collapsible_if,
|
||||
clippy::identity_op,
|
||||
clippy::len_without_is_empty,
|
||||
clippy::len_zero,
|
||||
clippy::let_unit_value,
|
||||
clippy::many_single_char_names,
|
||||
clippy::needless_range_loop,
|
||||
clippy::new_without_default,
|
||||
clippy::neg_cmp_op_on_partial_ord,
|
||||
clippy::range_plus_one,
|
||||
clippy::too_many_arguments,
|
||||
clippy::trivially_copy_pass_by_ref,
|
||||
clippy::type_complexity,
|
||||
clippy::unreadable_literal,
|
||||
missing_copy_implementations,
|
||||
missing_debug_implementations,
|
||||
non_camel_case_types,
|
||||
non_snake_case,
|
||||
unsafe_code
|
||||
)]
|
||||
// `#[derive(...)]` uses `trivial_numeric_casts` and `unused_qualifications`
|
||||
// internally.
|
||||
#![deny(missing_docs, unused_qualifications, variant_size_differences)]
|
||||
#![forbid(unused_results)]
|
||||
#![no_std]
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
extern crate alloc;
|
||||
|
||||
#[macro_use]
|
||||
mod debug;
|
||||
|
||||
#[macro_use]
|
||||
pub mod test;
|
||||
|
||||
#[macro_use]
|
||||
mod arithmetic;
|
||||
|
||||
#[macro_use]
|
||||
mod bssl;
|
||||
|
||||
#[macro_use]
|
||||
mod polyfill;
|
||||
|
||||
pub mod aead;
|
||||
pub mod agreement;
|
||||
|
||||
mod bits;
|
||||
|
||||
pub(crate) mod c;
|
||||
pub mod constant_time;
|
||||
|
||||
pub mod io;
|
||||
|
||||
mod cpu;
|
||||
pub mod digest;
|
||||
mod ec;
|
||||
mod endian;
|
||||
pub mod error;
|
||||
pub mod hkdf;
|
||||
pub mod hmac;
|
||||
mod limb;
|
||||
pub mod pbkdf2;
|
||||
pub mod pkcs8;
|
||||
pub mod rand;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
mod rsa;
|
||||
|
||||
pub mod signature;
|
||||
|
||||
mod sealed {
|
||||
/// Traits that are designed to only be implemented internally in *ring*.
|
||||
//
|
||||
// Usage:
|
||||
// ```
|
||||
// use crate::sealed;
|
||||
//
|
||||
// pub trait MyType: sealed::Sealed {
|
||||
// // [...]
|
||||
// }
|
||||
//
|
||||
// impl sealed::Sealed for MyType {}
|
||||
// ```
|
||||
pub trait Sealed {}
|
||||
}
|
||||
604
zeroidc/vendor/ring/src/limb.rs
vendored
Normal file
604
zeroidc/vendor/ring/src/limb.rs
vendored
Normal file
@@ -0,0 +1,604 @@
|
||||
// Copyright 2016 David Judd.
|
||||
// Copyright 2016 Brian Smith.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
//! Unsigned multi-precision integer arithmetic.
|
||||
//!
|
||||
//! Limbs ordered least-significant-limb to most-significant-limb. The bits
|
||||
//! limbs use the native endianness.
|
||||
|
||||
use crate::{c, error};
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::bits;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use core::num::Wrapping;
|
||||
|
||||
// XXX: Not correct for x32 ABIs.
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type Limb = u64;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub type Limb = u32;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub const LIMB_BITS: usize = 64;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub const LIMB_BITS: usize = 32;
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[repr(u64)]
|
||||
pub enum LimbMask {
|
||||
True = 0xffff_ffff_ffff_ffff,
|
||||
False = 0,
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[repr(u32)]
|
||||
pub enum LimbMask {
|
||||
True = 0xffff_ffff,
|
||||
False = 0,
|
||||
}
|
||||
|
||||
pub const LIMB_BYTES: usize = (LIMB_BITS + 7) / 8;
|
||||
|
||||
#[inline]
|
||||
pub fn limbs_equal_limbs_consttime(a: &[Limb], b: &[Limb]) -> LimbMask {
|
||||
extern "C" {
|
||||
fn LIMBS_equal(a: *const Limb, b: *const Limb, num_limbs: c::size_t) -> LimbMask;
|
||||
}
|
||||
|
||||
assert_eq!(a.len(), b.len());
|
||||
unsafe { LIMBS_equal(a.as_ptr(), b.as_ptr(), a.len()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn limbs_less_than_limbs_consttime(a: &[Limb], b: &[Limb]) -> LimbMask {
|
||||
assert_eq!(a.len(), b.len());
|
||||
unsafe { LIMBS_less_than(a.as_ptr(), b.as_ptr(), b.len()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn limbs_less_than_limbs_vartime(a: &[Limb], b: &[Limb]) -> bool {
|
||||
limbs_less_than_limbs_consttime(a, b) == LimbMask::True
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn limbs_less_than_limb_constant_time(a: &[Limb], b: Limb) -> LimbMask {
|
||||
unsafe { LIMBS_less_than_limb(a.as_ptr(), b, a.len()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn limbs_are_zero_constant_time(limbs: &[Limb]) -> LimbMask {
|
||||
unsafe { LIMBS_are_zero(limbs.as_ptr(), limbs.len()) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[inline]
|
||||
pub fn limbs_are_even_constant_time(limbs: &[Limb]) -> LimbMask {
|
||||
unsafe { LIMBS_are_even(limbs.as_ptr(), limbs.len()) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[inline]
|
||||
pub fn limbs_equal_limb_constant_time(a: &[Limb], b: Limb) -> LimbMask {
|
||||
unsafe { LIMBS_equal_limb(a.as_ptr(), b, a.len()) }
|
||||
}
|
||||
|
||||
/// Returns the number of bits in `a`.
|
||||
//
|
||||
// This strives to be constant-time with respect to the values of all bits
|
||||
// except the most significant bit. This does not attempt to be constant-time
|
||||
// with respect to `a.len()` or the value of the result or the value of the
|
||||
// most significant bit (It's 1, unless the input is zero, in which case it's
|
||||
// zero.)
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn limbs_minimal_bits(a: &[Limb]) -> bits::BitLength {
|
||||
for num_limbs in (1..=a.len()).rev() {
|
||||
let high_limb = a[num_limbs - 1];
|
||||
|
||||
// Find the number of set bits in |high_limb| by a linear scan from the
|
||||
// most significant bit to the least significant bit. This works great
|
||||
// for the most common inputs because usually the most significant bit
|
||||
// it set.
|
||||
for high_limb_num_bits in (1..=LIMB_BITS).rev() {
|
||||
let shifted = unsafe { LIMB_shr(high_limb, high_limb_num_bits - 1) };
|
||||
if shifted != 0 {
|
||||
return bits::BitLength::from_usize_bits(
|
||||
((num_limbs - 1) * LIMB_BITS) + high_limb_num_bits,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No bits were set.
|
||||
bits::BitLength::from_usize_bits(0)
|
||||
}
|
||||
|
||||
/// Equivalent to `if (r >= m) { r -= m; }`
|
||||
#[inline]
|
||||
pub fn limbs_reduce_once_constant_time(r: &mut [Limb], m: &[Limb]) {
|
||||
assert_eq!(r.len(), m.len());
|
||||
unsafe { LIMBS_reduce_once(r.as_mut_ptr(), m.as_ptr(), m.len()) };
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AllowZero {
|
||||
No,
|
||||
Yes,
|
||||
}
|
||||
|
||||
/// Parses `input` into `result`, reducing it via conditional subtraction
|
||||
/// (mod `m`). Assuming 2**((self.num_limbs * LIMB_BITS) - 1) < m and
|
||||
/// m < 2**(self.num_limbs * LIMB_BITS), the value will be reduced mod `m` in
|
||||
/// constant time so that the result is in the range [0, m) if `allow_zero` is
|
||||
/// `AllowZero::Yes`, or [1, m) if `allow_zero` is `AllowZero::No`. `result` is
|
||||
/// padded with zeros to its length.
|
||||
pub fn parse_big_endian_in_range_partially_reduced_and_pad_consttime(
|
||||
input: untrusted::Input,
|
||||
allow_zero: AllowZero,
|
||||
m: &[Limb],
|
||||
result: &mut [Limb],
|
||||
) -> Result<(), error::Unspecified> {
|
||||
parse_big_endian_and_pad_consttime(input, result)?;
|
||||
limbs_reduce_once_constant_time(result, m);
|
||||
if allow_zero != AllowZero::Yes {
|
||||
if limbs_are_zero_constant_time(&result) != LimbMask::False {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses `input` into `result`, verifies that the value is less than
|
||||
/// `max_exclusive`, and pads `result` with zeros to its length. If `allow_zero`
|
||||
/// is not `AllowZero::Yes`, zero values are rejected.
|
||||
///
|
||||
/// This attempts to be constant-time with respect to the actual value *only if*
|
||||
/// the value is actually in range. In other words, this won't leak anything
|
||||
/// about a valid value, but it might leak small amounts of information about an
|
||||
/// invalid value (which constraint it failed).
|
||||
pub fn parse_big_endian_in_range_and_pad_consttime(
|
||||
input: untrusted::Input,
|
||||
allow_zero: AllowZero,
|
||||
max_exclusive: &[Limb],
|
||||
result: &mut [Limb],
|
||||
) -> Result<(), error::Unspecified> {
|
||||
parse_big_endian_and_pad_consttime(input, result)?;
|
||||
if limbs_less_than_limbs_consttime(&result, max_exclusive) != LimbMask::True {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
if allow_zero != AllowZero::Yes {
|
||||
if limbs_are_zero_constant_time(&result) != LimbMask::False {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses `input` into `result`, padding `result` with zeros to its length.
|
||||
/// This attempts to be constant-time with respect to the value but not with
|
||||
/// respect to the length; it is assumed that the length is public knowledge.
|
||||
pub fn parse_big_endian_and_pad_consttime(
|
||||
input: untrusted::Input,
|
||||
result: &mut [Limb],
|
||||
) -> Result<(), error::Unspecified> {
|
||||
if input.is_empty() {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
// `bytes_in_current_limb` is the number of bytes in the current limb.
|
||||
// It will be `LIMB_BYTES` for all limbs except maybe the highest-order
|
||||
// limb.
|
||||
let mut bytes_in_current_limb = input.len() % LIMB_BYTES;
|
||||
if bytes_in_current_limb == 0 {
|
||||
bytes_in_current_limb = LIMB_BYTES;
|
||||
}
|
||||
|
||||
let num_encoded_limbs = (input.len() / LIMB_BYTES)
|
||||
+ (if bytes_in_current_limb == LIMB_BYTES {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
});
|
||||
if num_encoded_limbs > result.len() {
|
||||
return Err(error::Unspecified);
|
||||
}
|
||||
|
||||
for r in &mut result[..] {
|
||||
*r = 0;
|
||||
}
|
||||
|
||||
// XXX: Questionable as far as constant-timedness is concerned.
|
||||
// TODO: Improve this.
|
||||
input.read_all(error::Unspecified, |input| {
|
||||
for i in 0..num_encoded_limbs {
|
||||
let mut limb: Limb = 0;
|
||||
for _ in 0..bytes_in_current_limb {
|
||||
let b: Limb = input.read_byte()?.into();
|
||||
limb = (limb << 8) | b;
|
||||
}
|
||||
result[num_encoded_limbs - i - 1] = limb;
|
||||
bytes_in_current_limb = LIMB_BYTES;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn big_endian_from_limbs(limbs: &[Limb], out: &mut [u8]) {
|
||||
let num_limbs = limbs.len();
|
||||
let out_len = out.len();
|
||||
assert_eq!(out_len, num_limbs * LIMB_BYTES);
|
||||
for i in 0..num_limbs {
|
||||
let mut limb = limbs[i];
|
||||
for j in 0..LIMB_BYTES {
|
||||
out[((num_limbs - i - 1) * LIMB_BYTES) + (LIMB_BYTES - j - 1)] = (limb & 0xff) as u8;
|
||||
limb >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub type Window = Limb;
|
||||
|
||||
/// Processes `limbs` as a sequence of 5-bit windows, folding the windows from
|
||||
/// most significant to least significant and returning the accumulated result.
|
||||
/// The first window will be mapped by `init` to produce the initial value for
|
||||
/// the accumulator. Then `f` will be called to fold the accumulator and the
|
||||
/// next window until all windows are processed. When the input's bit length
|
||||
/// isn't divisible by 5, the window passed to `init` will be partial; all
|
||||
/// windows passed to `fold` will be full.
|
||||
///
|
||||
/// This is designed to avoid leaking the contents of `limbs` through side
|
||||
/// channels as long as `init` and `fold` are side-channel free.
|
||||
///
|
||||
/// Panics if `limbs` is empty.
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn fold_5_bit_windows<R, I: FnOnce(Window) -> R, F: Fn(R, Window) -> R>(
|
||||
limbs: &[Limb],
|
||||
init: I,
|
||||
fold: F,
|
||||
) -> R {
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
struct BitIndex(Wrapping<c::size_t>);
|
||||
|
||||
const WINDOW_BITS: Wrapping<c::size_t> = Wrapping(5);
|
||||
|
||||
extern "C" {
|
||||
fn LIMBS_window5_split_window(
|
||||
lower_limb: Limb,
|
||||
higher_limb: Limb,
|
||||
index_within_word: BitIndex,
|
||||
) -> Window;
|
||||
fn LIMBS_window5_unsplit_window(limb: Limb, index_within_word: BitIndex) -> Window;
|
||||
}
|
||||
|
||||
let num_limbs = limbs.len();
|
||||
let mut window_low_bit = {
|
||||
let num_whole_windows = (num_limbs * LIMB_BITS) / 5;
|
||||
let mut leading_bits = (num_limbs * LIMB_BITS) - (num_whole_windows * 5);
|
||||
if leading_bits == 0 {
|
||||
leading_bits = WINDOW_BITS.0;
|
||||
}
|
||||
BitIndex(Wrapping(LIMB_BITS - leading_bits))
|
||||
};
|
||||
|
||||
let initial_value = {
|
||||
let leading_partial_window =
|
||||
unsafe { LIMBS_window5_split_window(*limbs.last().unwrap(), 0, window_low_bit) };
|
||||
window_low_bit.0 -= WINDOW_BITS;
|
||||
init(leading_partial_window)
|
||||
};
|
||||
|
||||
let mut low_limb = 0;
|
||||
limbs
|
||||
.iter()
|
||||
.rev()
|
||||
.fold(initial_value, |mut acc, current_limb| {
|
||||
let higher_limb = low_limb;
|
||||
low_limb = *current_limb;
|
||||
|
||||
if window_low_bit.0 > Wrapping(LIMB_BITS) - WINDOW_BITS {
|
||||
let window =
|
||||
unsafe { LIMBS_window5_split_window(low_limb, higher_limb, window_low_bit) };
|
||||
window_low_bit.0 -= WINDOW_BITS;
|
||||
acc = fold(acc, window);
|
||||
};
|
||||
while window_low_bit.0 < Wrapping(LIMB_BITS) {
|
||||
let window = unsafe { LIMBS_window5_unsplit_window(low_limb, window_low_bit) };
|
||||
// The loop exits when this subtraction underflows, causing `window_low_bit` to
|
||||
// wrap around to a very large value.
|
||||
window_low_bit.0 -= WINDOW_BITS;
|
||||
acc = fold(acc, window);
|
||||
}
|
||||
window_low_bit.0 += Wrapping(LIMB_BITS); // "Fix" the underflow.
|
||||
|
||||
acc
|
||||
})
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#[cfg(feature = "alloc")]
|
||||
fn LIMB_shr(a: Limb, shift: c::size_t) -> Limb;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
fn LIMBS_are_even(a: *const Limb, num_limbs: c::size_t) -> LimbMask;
|
||||
fn LIMBS_are_zero(a: *const Limb, num_limbs: c::size_t) -> LimbMask;
|
||||
#[cfg(feature = "alloc")]
|
||||
fn LIMBS_equal_limb(a: *const Limb, b: Limb, num_limbs: c::size_t) -> LimbMask;
|
||||
fn LIMBS_less_than(a: *const Limb, b: *const Limb, num_limbs: c::size_t) -> LimbMask;
|
||||
#[cfg(feature = "alloc")]
|
||||
fn LIMBS_less_than_limb(a: *const Limb, b: Limb, num_limbs: c::size_t) -> LimbMask;
|
||||
fn LIMBS_reduce_once(r: *mut Limb, m: *const Limb, num_limbs: c::size_t);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const MAX: Limb = LimbMask::True as Limb;
|
||||
|
||||
#[test]
|
||||
fn test_limbs_are_even() {
|
||||
static EVENS: &[&[Limb]] = &[
|
||||
&[],
|
||||
&[0],
|
||||
&[2],
|
||||
&[0, 0],
|
||||
&[2, 0],
|
||||
&[0, 1],
|
||||
&[0, 2],
|
||||
&[0, 3],
|
||||
&[0, 0, 0, 0, MAX],
|
||||
];
|
||||
for even in EVENS {
|
||||
assert_eq!(limbs_are_even_constant_time(even), LimbMask::True);
|
||||
}
|
||||
static ODDS: &[&[Limb]] = &[
|
||||
&[1],
|
||||
&[3],
|
||||
&[1, 0],
|
||||
&[3, 0],
|
||||
&[1, 1],
|
||||
&[1, 2],
|
||||
&[1, 3],
|
||||
&[1, 0, 0, 0, MAX],
|
||||
];
|
||||
for odd in ODDS {
|
||||
assert_eq!(limbs_are_even_constant_time(odd), LimbMask::False);
|
||||
}
|
||||
}
|
||||
|
||||
static ZEROES: &[&[Limb]] = &[
|
||||
&[],
|
||||
&[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, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
];
|
||||
|
||||
static NONZEROES: &[&[Limb]] = &[
|
||||
&[1],
|
||||
&[0, 1],
|
||||
&[1, 1],
|
||||
&[1, 0, 0, 0],
|
||||
&[0, 1, 0, 0],
|
||||
&[0, 0, 1, 0],
|
||||
&[0, 0, 0, 1],
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_limbs_are_zero() {
|
||||
for zero in ZEROES {
|
||||
assert_eq!(limbs_are_zero_constant_time(zero), LimbMask::True);
|
||||
}
|
||||
for nonzero in NONZEROES {
|
||||
assert_eq!(limbs_are_zero_constant_time(nonzero), LimbMask::False);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_limbs_equal_limb() {
|
||||
for zero in ZEROES {
|
||||
assert_eq!(limbs_equal_limb_constant_time(zero, 0), LimbMask::True);
|
||||
}
|
||||
for nonzero in NONZEROES {
|
||||
assert_eq!(limbs_equal_limb_constant_time(nonzero, 0), LimbMask::False);
|
||||
}
|
||||
static EQUAL: &[(&[Limb], Limb)] = &[
|
||||
(&[1], 1),
|
||||
(&[MAX], MAX),
|
||||
(&[1, 0], 1),
|
||||
(&[MAX, 0, 0], MAX),
|
||||
(&[0b100], 0b100),
|
||||
(&[0b100, 0], 0b100),
|
||||
];
|
||||
for &(a, b) in EQUAL {
|
||||
assert_eq!(limbs_equal_limb_constant_time(a, b), LimbMask::True);
|
||||
}
|
||||
static UNEQUAL: &[(&[Limb], Limb)] = &[
|
||||
(&[0], 1),
|
||||
(&[2], 1),
|
||||
(&[3], 1),
|
||||
(&[1, 1], 1),
|
||||
(&[0b100, 0b100], 0b100),
|
||||
(&[1, 0, 0b100, 0, 0, 0, 0, 0], 1),
|
||||
(&[1, 0, 0, 0, 0, 0, 0, 0b100], 1),
|
||||
(&[MAX, MAX], MAX),
|
||||
(&[MAX, 1], MAX),
|
||||
];
|
||||
for &(a, b) in UNEQUAL {
|
||||
assert_eq!(limbs_equal_limb_constant_time(a, b), LimbMask::False);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "alloc")]
|
||||
fn test_limbs_less_than_limb_constant_time() {
|
||||
static LESSER: &[(&[Limb], Limb)] = &[
|
||||
(&[0], 1),
|
||||
(&[0, 0], 1),
|
||||
(&[1, 0], 2),
|
||||
(&[2, 0], 3),
|
||||
(&[2, 0], 3),
|
||||
(&[MAX - 1], MAX),
|
||||
(&[MAX - 1, 0], MAX),
|
||||
];
|
||||
for &(a, b) in LESSER {
|
||||
assert_eq!(limbs_less_than_limb_constant_time(a, b), LimbMask::True);
|
||||
}
|
||||
static EQUAL: &[(&[Limb], Limb)] = &[
|
||||
(&[0], 0),
|
||||
(&[0, 0, 0, 0], 0),
|
||||
(&[1], 1),
|
||||
(&[1, 0, 0, 0, 0, 0, 0], 1),
|
||||
(&[MAX], MAX),
|
||||
];
|
||||
static GREATER: &[(&[Limb], Limb)] = &[
|
||||
(&[1], 0),
|
||||
(&[2, 0], 1),
|
||||
(&[3, 0, 0, 0], 1),
|
||||
(&[0, 1, 0, 0], 1),
|
||||
(&[0, 0, 1, 0], 1),
|
||||
(&[0, 0, 1, 1], 1),
|
||||
(&[MAX], MAX - 1),
|
||||
];
|
||||
for &(a, b) in EQUAL.iter().chain(GREATER.iter()) {
|
||||
assert_eq!(limbs_less_than_limb_constant_time(a, b), LimbMask::False);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_big_endian_and_pad_consttime() {
|
||||
const LIMBS: usize = 4;
|
||||
|
||||
{
|
||||
// Empty input.
|
||||
let inp = untrusted::Input::from(&[]);
|
||||
let mut result = [0; LIMBS];
|
||||
assert!(parse_big_endian_and_pad_consttime(inp, &mut result).is_err());
|
||||
}
|
||||
|
||||
// The input is longer than will fit in the given number of limbs.
|
||||
{
|
||||
let inp = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
let inp = untrusted::Input::from(&inp);
|
||||
let mut result = [0; 8 / LIMB_BYTES];
|
||||
assert!(parse_big_endian_and_pad_consttime(inp, &mut result[..]).is_err());
|
||||
}
|
||||
|
||||
// Less than a full limb.
|
||||
{
|
||||
let inp = [0xfe];
|
||||
let inp = untrusted::Input::from(&inp);
|
||||
let mut result = [0; LIMBS];
|
||||
assert_eq!(
|
||||
Ok(()),
|
||||
parse_big_endian_and_pad_consttime(inp, &mut result[..])
|
||||
);
|
||||
assert_eq!(&[0xfe, 0, 0, 0], &result);
|
||||
}
|
||||
|
||||
// A whole limb for 32-bit, half a limb for 64-bit.
|
||||
{
|
||||
let inp = [0xbe, 0xef, 0xf0, 0x0d];
|
||||
let inp = untrusted::Input::from(&inp);
|
||||
let mut result = [0; LIMBS];
|
||||
assert_eq!(Ok(()), parse_big_endian_and_pad_consttime(inp, &mut result));
|
||||
assert_eq!(&[0xbeeff00d, 0, 0, 0], &result);
|
||||
}
|
||||
|
||||
// XXX: This is a weak set of tests. TODO: expand it.
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_big_endian_from_limbs_same_length() {
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
let limbs = [
|
||||
0xbccddeef, 0x89900aab, 0x45566778, 0x01122334, 0xddeeff00, 0x99aabbcc, 0x55667788,
|
||||
0x11223344,
|
||||
];
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
let limbs = [
|
||||
0x8990_0aab_bccd_deef,
|
||||
0x0112_2334_4556_6778,
|
||||
0x99aa_bbcc_ddee_ff00,
|
||||
0x1122_3344_5566_7788,
|
||||
];
|
||||
|
||||
let expected = [
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
|
||||
0xff, 0x00, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x90, 0x0a, 0xab,
|
||||
0xbc, 0xcd, 0xde, 0xef,
|
||||
];
|
||||
|
||||
let mut out = [0xabu8; 32];
|
||||
big_endian_from_limbs(&limbs[..], &mut out);
|
||||
assert_eq!(&out[..], &expected[..]);
|
||||
}
|
||||
|
||||
#[should_panic]
|
||||
#[test]
|
||||
fn test_big_endian_from_limbs_fewer_limbs() {
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
// Two fewer limbs.
|
||||
let limbs = [
|
||||
0xbccddeef, 0x89900aab, 0x45566778, 0x01122334, 0xddeeff00, 0x99aabbcc,
|
||||
];
|
||||
|
||||
// One fewer limb.
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
let limbs = [
|
||||
0x8990_0aab_bccd_deef,
|
||||
0x0112_2334_4556_6778,
|
||||
0x99aa_bbcc_ddee_ff00,
|
||||
];
|
||||
|
||||
let mut out = [0xabu8; 32];
|
||||
|
||||
big_endian_from_limbs(&limbs[..], &mut out);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_limbs_minimal_bits() {
|
||||
const ALL_ONES: Limb = LimbMask::True as Limb;
|
||||
static CASES: &[(&[Limb], usize)] = &[
|
||||
(&[], 0),
|
||||
(&[0], 0),
|
||||
(&[ALL_ONES], LIMB_BITS),
|
||||
(&[ALL_ONES, 0], LIMB_BITS),
|
||||
(&[ALL_ONES, 1], LIMB_BITS + 1),
|
||||
(&[0, 0], 0),
|
||||
(&[1, 0], 1),
|
||||
(&[0, 1], LIMB_BITS + 1),
|
||||
(&[0, ALL_ONES], 2 * LIMB_BITS),
|
||||
(&[ALL_ONES, ALL_ONES], 2 * LIMB_BITS),
|
||||
(&[ALL_ONES, ALL_ONES >> 1], 2 * LIMB_BITS - 1),
|
||||
(&[ALL_ONES, 0b100_0000], LIMB_BITS + 7),
|
||||
(&[ALL_ONES, 0b101_0000], LIMB_BITS + 7),
|
||||
(&[ALL_ONES, ALL_ONES >> 1], LIMB_BITS + (LIMB_BITS) - 1),
|
||||
];
|
||||
for (limbs, bits) in CASES {
|
||||
assert_eq!(limbs_minimal_bits(limbs).as_usize_bits(), *bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user