2022-04-25 21:30:42 +02:00

192 lines
5.4 KiB
C

/**
This library performs arbitrary precision arithmetic operations.
For more details, please refer to the source files and function headers.
Copyright (C) 2019, Download-Fritz. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef BIG_NUM_LIB_H
#define BIG_NUM_LIB_H
#include "CryptoInternal.h"
///
/// A BIGNUM word. This is at best an integer of the platform's natural size
/// to optimize memory accesses and arithmetic operation count.
///
typedef UINTN OC_BN_WORD;
//
// Declarations regarding the Word size.
//
#define OC_BN_WORD_SIZE (sizeof (OC_BN_WORD))
#define OC_BN_WORD_NUM_BITS ((OC_BN_NUM_BITS) (OC_BN_WORD_SIZE * OC_CHAR_BIT))
//
// Declarations regarding the maximum size of OC_BN structures.
//
typedef UINT16 OC_BN_NUM_WORDS;
typedef UINT32 OC_BN_SIZE;
typedef UINT32 OC_BN_NUM_BITS;
#define OC_BN_MAX_SIZE ((OC_BN_SIZE) SIZE_64KB)
#define OC_BN_MAX_LEN ((OC_BN_NUM_WORDS) (OC_BN_MAX_SIZE / OC_BN_WORD_SIZE))
/**
The size, in Bytes, required to store a BigNum with NumWords words.
@param[in] NumWords The number of Words. Must be at most OC_BN_MAX_LEN.
**/
#define OC_BN_SIZE(NumWords) \
((OC_BN_SIZE) (NumWords) * OC_BN_WORD_SIZE)
STATIC_ASSERT (
OC_BN_MAX_LEN <= MAX_UINTN / OC_BN_WORD_SIZE,
"The definition of OC_BN_SIZE may cause an overflow"
);
/**
The size, in Bits, required to store a BigNum with NumWords words.
@param[in] NumWords The number of Words. Must be at most OC_BN_MAX_LEN.
**/
#define OC_BN_BITS(NumWords) \
((OC_BN_NUM_BITS) OC_BN_SIZE (NumWords) * OC_CHAR_BIT)
STATIC_ASSERT (
OC_BN_BITS (OC_BN_MAX_LEN) <= MAX_UINTN / OC_CHAR_BIT,
"The definition of OC_BN_BITS may cause an overflow"
);
//
// Primitives
//
/**
Parses a data array into a number. The buffer size must be a multiple of the
Word size. The length of Result must precisely fit the required size.
@param[in,out] Result The buffer to store the result in.
@param[in] NumWords The number of Words of Result.
@param[in] Buffer The buffer to parse.
@param[in] BufferSize The size, in bytes, of Buffer.
**/
VOID
BigNumParseBuffer (
IN OUT OC_BN_WORD *Result,
IN OC_BN_NUM_WORDS NumWords,
IN CONST UINT8 *Buffer,
IN UINTN BufferSize
);
/**
Swaps the byte order of Word.
@param[in] Word The Word to swap.
@returns The byte-swapped value of Word.
**/
OC_BN_WORD
BigNumSwapWord (
IN OC_BN_WORD Word
);
//
// Montgomery arithmetics
//
#define OC_BN_MONT_MAX_LEN (OC_BN_MAX_LEN / 2U - 1U)
#define OC_BN_MONT_MAX_SIZE (OC_BN_SIZE (OC_BN_MONT_MAX_LEN))
/**
The length, in BigNum words, of RSqr.
@param[in] NumWords The number of Words of N. Must be at most
OC_BN_MONT_MAX_LEN.
**/
#define OC_BN_MONT_RSQR_LEN(NumWords) ((OC_BN_NUM_WORDS) (((NumWords) + 1U) * 2U))
STATIC_ASSERT (
OC_BN_MONT_RSQR_LEN (OC_BN_MONT_MAX_LEN) == OC_BN_MAX_LEN,
"The definition of OC_BN_MONT_RSQR_LEN is faulty"
);
/**
The size, in Bytes, of RSqr.
@param[in] NumWords The number of Words of N. Must be at most
OC_BN_MONT_MAX_LEN.
**/
#define OC_BN_MONT_RSQR_SIZE(NumWords) (OC_BN_SIZE (OC_BN_MONT_RSQR_LEN (NumWords)))
/**
1 + 2 * NumWords for RSqr, and then twice more than that for Mod.
@param[in] NumWords The number of Words of RSqrMod and N. Must be at most
OC_BN_MONT_MAX_LEN.
**/
#define BIG_NUM_MONT_PARAMS_SCRATCH_SIZE(NumWords) \
(OC_BN_MONT_RSQR_SIZE (NumWords) * 3U)
STATIC_ASSERT (
OC_BN_MONT_RSQR_SIZE (OC_BN_MONT_MAX_SIZE) <= MAX_UINTN / 3,
"The definition of BIG_NUM_MONT_PARAMS_SCRATCH_SIZE may cause an overflow"
);
/**
Calculates the Montgomery Inverse and R^2 mod N.
@param[in,out] RSqrMod The buffer to return R^2 mod N into.
@param[in] NumWords The number of Words of RSqrMod and N. Must be at most
OC_BN_MONT_MAX_LEN.
@param[in] N The Montgomery Modulus.
@param[in] Scratch Scratch buffer BIG_NUM_MONT_PARAMS_SCRATCH_SIZE(NumWords).
@returns The Montgomery Inverse of N.
**/
OC_BN_WORD
BigNumCalculateMontParams (
IN OUT OC_BN_WORD *RSqrMod,
IN OC_BN_NUM_WORDS NumWords,
IN CONST OC_BN_WORD *N,
IN OC_BN_WORD *Scratch
);
/**
Caulculates the exponentiation of A with B mod N.
@param[in,out] Result The buffer to return the result into.
@param[in] NumWords The number of Words of Result, A, N and RSqrMod.
@param[in] A The base.
@param[in] B The exponent.
@param[in] N The modulus.
@param[in] N0Inv The Montgomery Inverse of N.
@param[in] RSqrMod Montgomery's R^2 mod N.
@param[in] ATmp Scratch buffer of NumWords.
@returns Whether the operation was completes successfully.
**/
BOOLEAN
BigNumPowMod (
IN OUT OC_BN_WORD *Result,
IN OC_BN_NUM_WORDS NumWords,
IN CONST OC_BN_WORD *A,
IN UINT32 B,
IN CONST OC_BN_WORD *N,
IN OC_BN_WORD N0Inv,
IN CONST OC_BN_WORD *RSqrMod,
IN OC_BN_WORD *ATmp
);
#endif // BIG_NUM_LIB_H