[Mod] fsbl 替换为开源版本

开源fsbl仓库:https://hub.yzuu.cf/milkv-duo/fsbl.git
This commit is contained in:
gaoyang3513
2024-04-02 21:49:47 +08:00
parent 362832ac66
commit 6128fe43b9
2473 changed files with 263022 additions and 22405 deletions

7
fsbl/.gitignore vendored
View File

@ -1,6 +1 @@
*.d
fip.bin
build_message.o
blmacros.dis
build/cvi_board_memmap.h
build/
build/

View File

@ -1,3 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
.PHONY: FORCE
# Default goal is build all images
.DEFAULT_GOAL := all

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef __BL2_HELPER_H__
#define __BL2_HELPER_H__

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef __CPU_HELP_H__
#define __CPU_HELP_H__

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef __CPU_H__
#define __CPU_H__

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef __ARCH_HELPERS_H__
#define __ARCH_HELPERS_H__
//#include <cpu.h> /* for additional register definitions */
#include <cdefs.h> /* For __dead2 */
#include <stdint.h>
#include <sys/types.h>

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef __CPU_HELP_H__
#define __CPU_HELP_H__

View File

@ -1,110 +1,110 @@
# CHANGE LOG FOR BIGDIGITS
## Changes in Version 2.6
_Version 2.6.1 (Released 31 March 2016)_
* Added new functions to perform modular arithmetic operations, particularly useful for doing computations in a prime field for elliptic curves:
* `mpModSquare`, `bdModSquare` to compute `a = x^2 (mod m)`
* `mpModSqrt`, `bdModSqrt` to compute a square root modulo a prime p
* `mpModHalve`, `bdModHalve` to compute `a = x / 2 (mod p)`
* `mpModAdd`, `bdModAdd` and `mpModSub`, `bdModSub` to compute `w = u <20> v (mod m)` quickly for u and v in the range `[0, m-1]`.
* The function `mpModSpecial` to compute `u = v (mod m)` in the special case where v is known to be in the range `[0, km]` for k a small integer. This is faster than `mpModulo`.
* Added functions `mpToShort`, `bdToShort` to convert a multiprecision integer to a single digit.
* Added functions `mpShortIsEqual`, `bdmpShortIsEqual` to check if a multiprecision integer is equal to a single digit.
* Added the explicit constant-time comparison functions.
* `mpEqual_ct()`, `bdIsEqual_ct()`
* `mpIsZero_ct()`, `bdIsZero_ct()`
* `mpCompare_ct()`, `bdCompare_ct()`
* Reversed the change in v2.5 to make the comparison functions constant-time by default. The original comparison functions are now _not_ constant-time, as they were before v2.5\. The user must explicitly select the constant-time variant (ending **_ct**). To summarize: the functions `mpEqual`, `bdIsEqual`, `mpIsZero`, `bdIsZero`, `mpCompare` and `bdCompare` are _not_ constant-time in v2.6.
> _Comment:_ We realised after we made the change in v2.5 that the majority of comparison operations in our own code were simple checks for special cases and were not comparing secret values, so they did not need the more expensive constant-time operations. There were only a few occasions where we did comparisons on secret values and these were easily found and explicitly changed to do a constant-time comparison. So, sorry, we shouldn't have changed the default behaviour in v2.5\. It's back now to how it was before.
* Added the functions `mpCompileTime`, `bdCompileTime` to show the time and date of compilation.
* Added the function `mpPrintBits` to print the value in 0/1 bit format.
* Added the option to specify the global preprocessor definition, say, `MAX_FIXED_BIT_LENGTH=640` when using the `NO_ALLOCS` option for the "mp" functions. This allows you to change the maximum fixed length of arrays without editing the core source code.
* Increased the size of the fixed-length buffers in the `mpPrint*()` functions to avoid buffer overflows
* Fixed an issue with the `mpPrint*()` functions when displaying zero values.
* Added the `bdNewVars` and `bdFreeVars` functions to allow "bulk" creation and destruction of "bd" variables in a single line of code.
## Changes in Version 2.5
_Version 2.5 (Released 22 October 2015)_
* Changed license conditions to Mozilla Public License, v. 2.0.
* Fixed `bdShortMult` to catch empty `u` parameter.
* Fixed `bdPrintBits` to print "0" if bit length is zero.
* Changed comparison functions to be constant-time by default. Retained the old, quicker functions as `_q` variants.
* `mpEqual` `bdIsEqual` `mpEqual_q` `bdIsEqual_q`
* `mpIsZero` `bdIsZero` `mpIsZero_q` `bdIsZero_q`
* `mpCompare` `bdCompare` `mpCompare_q` `bdCompare_q`
* Added constant-time modular exponentiation functions `bdModExp_ct` and `mpModExp_ct`.
* Added `mpPrintDecimalSigned` function to display negative numbers ("**mp**" only).
## Changes in Version 2.4
_Version 2.4 (Released 27 April 2013)_
* Added markup for Doxygen documentation to produce a manual in CHM and HTML formats.
* Updated the "pretty-good" internal RNG functions in `bigdRand` and `bigdigitsRand` to improve the seeding of the ANSI X9.31 PRNG algorithm.
* Fixed the `NO_ALLOCS` option so it does not use malloc with the `mpConv` functions (thanks to Kevin Kramb for pointing this out).
* Added the new functions `bdRandomOctets`, `bdRandomNumber` and `bdQuickRandBits`, which do various contortions you might want to do with random numbers.
* Updated the test source code modules.
## Changes in Version 2.3
_Version 2.3 (Released 11 November 2011)_
* Added new functions to compute the integer cube root: `bdCubeRoot` and `mpCubeRoot`.
* Updated and improved the integer square root functions: `bdSqrt` and `mpSqrt`.
* Added the more useful print functions with an optional prefix and suffix:
* `bdPrintHex` prints a bigdigit number in hex format.
* `bdPrintDecimal` prints a bigdigit number in decimal format.and the equivalent mp functions `mpPrintHex` and `mpPrintDecimal`.
* Added the new function `bdPower` to compute the n-th power of a number `y = g^n`. Use this with caution as you can quickly run out of memory. It's meant for small exponents like n=3.
* Improved the efficiency of the greatest common divisor functions, `bdGcd` and `mpGcd`.
* Fixed the bug in `mpChs` (thanks to Valery Blazhnov).
* Fixed the bug in `mpAlloc` which would fail if you called `bdSetDigit(b, 0)` (thanks to "Radistao").
## Changes in Version 2.2
_Version 2.2 (Released 31 July 2008)_
* Added sliding-window exponentiation to speed up the ModExp functions.
* Added new bd functions:
* `bdJacobi` computes the Jacobi (Legendre) symbol.
* `bdGetBit` returns the value of a bit at a given position in a number.
* `bdSetBit` sets the bit at a given position in a number.
* `bdNotBits` computes bitwise a = NOT a.
* Added the new functions `mpIsNegative`, `mpChs` and `mpAbs` in anticipation of adding full signed integer functionality in a later version.
* Added the `NO_ALLOCS` option to compile the "mp" library without using any memory allocation.
* Added the `USE_64WITH32` option to use the 64-bit integer types (`long long`) if available on a 32-bit machine.
* Improved the zeroisation and destroy macros.
* Moved the type declarations for the exact-width types to a separate include file.
* Re-organised and re-named the ancillary source and include files (yet again!).
* Deprecated the `bd*Ex` functions in favour of re-named "safe" `bd*_s` functions.
## Changes in Version 2.1
_Version 2.1 (Released 23 August 2006)_
* Added support for 64-bit compilers.
* Added fudge so opaque pointers will work with C++ compilers.
* Added new functions:
* `bdSqrt` computes the `integer' square root, s = floor(sqrt(x)).
* `bdModPowerOf2` computes a = a (mod 2^L).
* `bdXorBits` computes bitwise a = b XOR c.
* `bdOrBits` computes bitwise a = b OR c.
* `bdAndBits` computes bitwise a = b AND c.
* `bdVersion` returns version number as an integer = major*1000+minor*100+release*10+uses_asm(0|1).
* `bdRandomBits` generates a random BIGD number up to n bits long (i.e. r = [0, 2^n]) using the internal RNG.
* Removed the shift limit on `bdShiftLeft` and `bdShiftRight`. This was previously limited to a maximum of 32 bits. It will now shift by any value - well, any value up to `SIZE_MAX`.
* Re-organised the source and include files for the internal random number generator functions to avoid having to include the `spRandom` modules when they are not needed.
* Fixed up inconsistencies in the documentation for the `bdConv*` functions.
* Made minor change to `mpIsPrime` to comply with ANSI X.42-2003 Annex F.1.1 "Range of bases in Miller-Rabin test".
* Made minor improvements to the `spBetterRand` function.
* Fixed bugs in `bdConvertHex`, `bdGetBit` and `bdSetBit`.
* Made various minor changes in the code to avoid warning messages when compiling with the `-Wall -pedantic` options.
# CHANGE LOG FOR BIGDIGITS
## Changes in Version 2.6
_Version 2.6.1 (Released 31 March 2016)_
* Added new functions to perform modular arithmetic operations, particularly useful for doing computations in a prime field for elliptic curves:
* `mpModSquare`, `bdModSquare` to compute `a = x^2 (mod m)`
* `mpModSqrt`, `bdModSqrt` to compute a square root modulo a prime p
* `mpModHalve`, `bdModHalve` to compute `a = x / 2 (mod p)`
* `mpModAdd`, `bdModAdd` and `mpModSub`, `bdModSub` to compute `w = u <20> v (mod m)` quickly for u and v in the range `[0, m-1]`.
* The function `mpModSpecial` to compute `u = v (mod m)` in the special case where v is known to be in the range `[0, km]` for k a small integer. This is faster than `mpModulo`.
* Added functions `mpToShort`, `bdToShort` to convert a multiprecision integer to a single digit.
* Added functions `mpShortIsEqual`, `bdmpShortIsEqual` to check if a multiprecision integer is equal to a single digit.
* Added the explicit constant-time comparison functions.
* `mpEqual_ct()`, `bdIsEqual_ct()`
* `mpIsZero_ct()`, `bdIsZero_ct()`
* `mpCompare_ct()`, `bdCompare_ct()`
* Reversed the change in v2.5 to make the comparison functions constant-time by default. The original comparison functions are now _not_ constant-time, as they were before v2.5\. The user must explicitly select the constant-time variant (ending **_ct**). To summarize: the functions `mpEqual`, `bdIsEqual`, `mpIsZero`, `bdIsZero`, `mpCompare` and `bdCompare` are _not_ constant-time in v2.6.
> _Comment:_ We realised after we made the change in v2.5 that the majority of comparison operations in our own code were simple checks for special cases and were not comparing secret values, so they did not need the more expensive constant-time operations. There were only a few occasions where we did comparisons on secret values and these were easily found and explicitly changed to do a constant-time comparison. So, sorry, we shouldn't have changed the default behaviour in v2.5\. It's back now to how it was before.
* Added the functions `mpCompileTime`, `bdCompileTime` to show the time and date of compilation.
* Added the function `mpPrintBits` to print the value in 0/1 bit format.
* Added the option to specify the global preprocessor definition, say, `MAX_FIXED_BIT_LENGTH=640` when using the `NO_ALLOCS` option for the "mp" functions. This allows you to change the maximum fixed length of arrays without editing the core source code.
* Increased the size of the fixed-length buffers in the `mpPrint*()` functions to avoid buffer overflows
* Fixed an issue with the `mpPrint*()` functions when displaying zero values.
* Added the `bdNewVars` and `bdFreeVars` functions to allow "bulk" creation and destruction of "bd" variables in a single line of code.
## Changes in Version 2.5
_Version 2.5 (Released 22 October 2015)_
* Changed license conditions to Mozilla Public License, v. 2.0.
* Fixed `bdShortMult` to catch empty `u` parameter.
* Fixed `bdPrintBits` to print "0" if bit length is zero.
* Changed comparison functions to be constant-time by default. Retained the old, quicker functions as `_q` variants.
* `mpEqual` `bdIsEqual` `mpEqual_q` `bdIsEqual_q`
* `mpIsZero` `bdIsZero` `mpIsZero_q` `bdIsZero_q`
* `mpCompare` `bdCompare` `mpCompare_q` `bdCompare_q`
* Added constant-time modular exponentiation functions `bdModExp_ct` and `mpModExp_ct`.
* Added `mpPrintDecimalSigned` function to display negative numbers ("**mp**" only).
## Changes in Version 2.4
_Version 2.4 (Released 27 April 2013)_
* Added markup for Doxygen documentation to produce a manual in CHM and HTML formats.
* Updated the "pretty-good" internal RNG functions in `bigdRand` and `bigdigitsRand` to improve the seeding of the ANSI X9.31 PRNG algorithm.
* Fixed the `NO_ALLOCS` option so it does not use malloc with the `mpConv` functions (thanks to Kevin Kramb for pointing this out).
* Added the new functions `bdRandomOctets`, `bdRandomNumber` and `bdQuickRandBits`, which do various contortions you might want to do with random numbers.
* Updated the test source code modules.
## Changes in Version 2.3
_Version 2.3 (Released 11 November 2011)_
* Added new functions to compute the integer cube root: `bdCubeRoot` and `mpCubeRoot`.
* Updated and improved the integer square root functions: `bdSqrt` and `mpSqrt`.
* Added the more useful print functions with an optional prefix and suffix:
* `bdPrintHex` prints a bigdigit number in hex format.
* `bdPrintDecimal` prints a bigdigit number in decimal format.and the equivalent mp functions `mpPrintHex` and `mpPrintDecimal`.
* Added the new function `bdPower` to compute the n-th power of a number `y = g^n`. Use this with caution as you can quickly run out of memory. It's meant for small exponents like n=3.
* Improved the efficiency of the greatest common divisor functions, `bdGcd` and `mpGcd`.
* Fixed the bug in `mpChs` (thanks to Valery Blazhnov).
* Fixed the bug in `mpAlloc` which would fail if you called `bdSetDigit(b, 0)` (thanks to "Radistao").
## Changes in Version 2.2
_Version 2.2 (Released 31 July 2008)_
* Added sliding-window exponentiation to speed up the ModExp functions.
* Added new bd functions:
* `bdJacobi` computes the Jacobi (Legendre) symbol.
* `bdGetBit` returns the value of a bit at a given position in a number.
* `bdSetBit` sets the bit at a given position in a number.
* `bdNotBits` computes bitwise a = NOT a.
* Added the new functions `mpIsNegative`, `mpChs` and `mpAbs` in anticipation of adding full signed integer functionality in a later version.
* Added the `NO_ALLOCS` option to compile the "mp" library without using any memory allocation.
* Added the `USE_64WITH32` option to use the 64-bit integer types (`long long`) if available on a 32-bit machine.
* Improved the zeroisation and destroy macros.
* Moved the type declarations for the exact-width types to a separate include file.
* Re-organised and re-named the ancillary source and include files (yet again!).
* Deprecated the `bd*Ex` functions in favour of re-named "safe" `bd*_s` functions.
## Changes in Version 2.1
_Version 2.1 (Released 23 August 2006)_
* Added support for 64-bit compilers.
* Added fudge so opaque pointers will work with C++ compilers.
* Added new functions:
* `bdSqrt` computes the `integer' square root, s = floor(sqrt(x)).
* `bdModPowerOf2` computes a = a (mod 2^L).
* `bdXorBits` computes bitwise a = b XOR c.
* `bdOrBits` computes bitwise a = b OR c.
* `bdAndBits` computes bitwise a = b AND c.
* `bdVersion` returns version number as an integer = major*1000+minor*100+release*10+uses_asm(0|1).
* `bdRandomBits` generates a random BIGD number up to n bits long (i.e. r = [0, 2^n]) using the internal RNG.
* Removed the shift limit on `bdShiftLeft` and `bdShiftRight`. This was previously limited to a maximum of 32 bits. It will now shift by any value - well, any value up to `SIZE_MAX`.
* Re-organised the source and include files for the internal random number generator functions to avoid having to include the `spRandom` modules when they are not needed.
* Fixed up inconsistencies in the documentation for the `bdConv*` functions.
* Made minor change to `mpIsPrime` to comply with ANSI X.42-2003 Annex F.1.1 "Range of bases in Miller-Rabin test".
* Made minor improvements to the `spBetterRand` function.
* Fixed bugs in `bdConvertHex`, `bdGetBit` and `bdSetBit`.
* Made various minor changes in the code to avoid warning messages when compiling with the `-Wall -pedantic` options.

View File

@ -1,373 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@ -1,74 +1,74 @@
# Linux/Cygwin gcc Makefile for bigdigits tests
# $Date: 2015-10-21 20:07:00 $
# $Revision: 2.5.0 $
# $Author: dai $
#
OBJECTS= bigd.o bigdigits.o bigdigitsRand.o bigdRand.o
INCLUDES= bigd.h bigdigits.h bigdtypes.h bigdRand.h bigdigitsRand.h
CFLAGS= -std=c99 -pedantic -Wall -Wpointer-arith -Wstrict-prototypes -Wno-format -O2
CC= gcc
%.o: %.c $(INCLUDES)
$(CC) $(CFLAGS) -c $<
# bigd "bd" tests
t_bdTest: t_bdTest.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdSimple: t_bdSimple.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRSA: t_bdRSA.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRSA1: t_bdRSA1.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdDSA: t_bdDSA.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRDSA: t_bdRDSA.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRsaCrack: t_bdRsaCrack.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRsaFactorN: t_bdRsaFactorN.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRandomOctets: t_bdRandomOctets.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS) -lm
t_bdQuickRandBits: t_bdQuickRandBits.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRSA_blinded: t_bdRSA_blinded.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
# bigdigits "mp" tests
t_mpTest: t_mpTest.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_mpRSA508: t_mpRSA508.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_mpJacobi: t_mpJacobi.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
# extra "sp" function tests
t_spExtras: t_spExtras.o spExtras.o
$(CC) $(CFLAGS) -o $@ $@.o spExtras.o $(OBJECTS) $(LDFLAGS)
spExtras.o: spExtras.c spExtras.h $(INCLUDES)
# Call functions from a C++ program
t_bdCPP: t_bdCPP.o $(INCLUDES) $(OBJECTS)
g++ $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
clean:
-rm -f *.o
# Linux/Cygwin gcc Makefile for bigdigits tests
# $Date: 2015-10-21 20:07:00 $
# $Revision: 2.5.0 $
# $Author: dai $
#
OBJECTS= bigd.o bigdigits.o bigdigitsRand.o bigdRand.o
INCLUDES= bigd.h bigdigits.h bigdtypes.h bigdRand.h bigdigitsRand.h
CFLAGS= -std=c99 -pedantic -Wall -Wpointer-arith -Wstrict-prototypes -Wno-format -O2
CC= gcc
%.o: %.c $(INCLUDES)
$(CC) $(CFLAGS) -c $<
# bigd "bd" tests
t_bdTest: t_bdTest.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdSimple: t_bdSimple.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRSA: t_bdRSA.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRSA1: t_bdRSA1.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdDSA: t_bdDSA.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRDSA: t_bdRDSA.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRsaCrack: t_bdRsaCrack.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRsaFactorN: t_bdRsaFactorN.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRandomOctets: t_bdRandomOctets.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS) -lm
t_bdQuickRandBits: t_bdQuickRandBits.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_bdRSA_blinded: t_bdRSA_blinded.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
# bigdigits "mp" tests
t_mpTest: t_mpTest.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_mpRSA508: t_mpRSA508.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
t_mpJacobi: t_mpJacobi.o $(INCLUDES) $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
# extra "sp" function tests
t_spExtras: t_spExtras.o spExtras.o
$(CC) $(CFLAGS) -o $@ $@.o spExtras.o $(OBJECTS) $(LDFLAGS)
spExtras.o: spExtras.c spExtras.h $(INCLUDES)
# Call functions from a C++ program
t_bdCPP: t_bdCPP.o $(INCLUDES) $(OBJECTS)
g++ $(CFLAGS) -o $@ $@.o $(OBJECTS) $(LDFLAGS)
clean:
-rm -f *.o

View File

@ -1,57 +1,57 @@
BIGDIGITS LIBRARY
Version 2.6.1 Released 2016-03-31.
Core Source Code Files
----------------------
bigd.c
bigd.h
bigdigits.c
bigdigits.h
bigdtypes.h
Use these for "pretty-good" random number routines
--------------------------------------------------
bigdRand.c
bigdRand.h
bigdigitsRand.c
bigdigitsRand.h
Additional Source Code Files
----------------------------
spExtras.c
spExtras.h
Test Source Code Files
----------------------
t_bdDSA.c
t_bdQuickRandBits.c
t_bdRandomOctets.c
t_bdRDSA.c
t_bdRSA.c
t_bdRSA1.c
t_bdRsaCrack.c
t_bdRsaFactorN.c
t_bdSimple.c
t_bdTest.c
t_mpJacobi.c
t_mpRSA508.c
t_mpTest.c
t_spExtras.c
t_bdCPP.cpp
t_bdRSA_blinded.c
t_mpModArith.c
Manual
------
BigDigits.chm
For more details on how to compile and so forth, see
<http://www.di-mgt.com.au/bigdigits.html>
For the online manual, see
<http://www.di-mgt.com.au/bigdigitsmanual/>
Please read the copyright notice and licence conditions in
LICENCE.txt.
BIGDIGITS LIBRARY
Version 2.6.1 Released 2016-03-31.
Core Source Code Files
----------------------
bigd.c
bigd.h
bigdigits.c
bigdigits.h
bigdtypes.h
Use these for "pretty-good" random number routines
--------------------------------------------------
bigdRand.c
bigdRand.h
bigdigitsRand.c
bigdigitsRand.h
Additional Source Code Files
----------------------------
spExtras.c
spExtras.h
Test Source Code Files
----------------------
t_bdDSA.c
t_bdQuickRandBits.c
t_bdRandomOctets.c
t_bdRDSA.c
t_bdRSA.c
t_bdRSA1.c
t_bdRsaCrack.c
t_bdRsaFactorN.c
t_bdSimple.c
t_bdTest.c
t_mpJacobi.c
t_mpRSA508.c
t_mpTest.c
t_spExtras.c
t_bdCPP.cpp
t_bdRSA_blinded.c
t_mpModArith.c
Manual
------
BigDigits.chm
For more details on how to compile and so forth, see
<http://www.di-mgt.com.au/bigdigits.html>
For the online manual, see
<http://www.di-mgt.com.au/bigdigitsmanual/>
Please read the copyright notice and licence conditions in
LICENCE.txt.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,78 +1,78 @@
/* $Id: bigdRand.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
/* Random number BIGD functions that rely on spBetterRand */
#include "bigdRand.h"
#include "bigdigitsRand.h"
#include <stdio.h>
bdigit_t bdRandDigit(void)
/* Return a random digit. */
{
return spBetterRand();
}
size_t bdRandomBits(BIGD a, size_t nbits)
/* Generate a random BIGD number <= 2^{nbits}-1 using internal RNG */
{
const int bits_per_digit = sizeof(bdigit_t) * 8;
size_t i;
int j;
bdigit_t r;
bdSetZero(a);
bdSetBit(a, nbits-1, 0);
r = bdRandDigit();
j = bits_per_digit;
for (i = 0; i < nbits; i++)
{
if (j <= 0)
{
r = bdRandDigit();
j = bits_per_digit;
}
bdSetBit(a, i, r & 0x1);
r >>= 1;
j--;
}
return i;
}
/** Generate array of random octets (bytes) using internal RNG.
This function is in the correct form for BD_RANDFUNC.
Seed is ignored here.
*/
int bdRandomOctets(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen)
{
return mpRandomOctets(bytes, nbytes, seed, seedlen);
}
size_t bdRandomNumber(BIGD a, BIGD n)
{ /* Generate a number in the range [0, n-1] */
size_t nbits = bdBitLength(n);
bdSetZero(a);
do {
bdRandomBits(a, nbits);
} while (bdCompare(a, n) >= 0);
return bdSizeof(a);
}
/* $Id: bigdRand.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
/* Random number BIGD functions that rely on spBetterRand */
#include "bigdRand.h"
#include "bigdigitsRand.h"
#include <stdio.h>
bdigit_t bdRandDigit(void)
/* Return a random digit. */
{
return spBetterRand();
}
size_t bdRandomBits(BIGD a, size_t nbits)
/* Generate a random BIGD number <= 2^{nbits}-1 using internal RNG */
{
const int bits_per_digit = sizeof(bdigit_t) * 8;
size_t i;
int j;
bdigit_t r;
bdSetZero(a);
bdSetBit(a, nbits-1, 0);
r = bdRandDigit();
j = bits_per_digit;
for (i = 0; i < nbits; i++)
{
if (j <= 0)
{
r = bdRandDigit();
j = bits_per_digit;
}
bdSetBit(a, i, r & 0x1);
r >>= 1;
j--;
}
return i;
}
/** Generate array of random octets (bytes) using internal RNG.
This function is in the correct form for BD_RANDFUNC.
Seed is ignored here.
*/
int bdRandomOctets(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen)
{
return mpRandomOctets(bytes, nbytes, seed, seedlen);
}
size_t bdRandomNumber(BIGD a, BIGD n)
{ /* Generate a number in the range [0, n-1] */
size_t nbits = bdBitLength(n);
bdSetZero(a);
do {
bdRandomBits(a, nbits);
} while (bdCompare(a, n) >= 0);
return bdSizeof(a);
}

View File

@ -1,69 +1,69 @@
/* $Id: bigdRand.h $ */
/** @file
Interface for BigDigits "bd" random number functions using a "pretty-good" internal RNG
@par The internal random number generator (RNG)
The internal RNG uses a variant of the random number generation algorithm
in Appendix A of ANSI X9.31-1998, but using the Tiny Encryption Algorithm (TEAX)
instead of the Data Encryption Algorithm (DEA).
It uses the current time and process ID as a seed.
Although not strictly crypto secure, it is "pretty good", and certainly much better than
anything using the built-in rand() function in C. Look at the source code and make your own call.
@par
If you want proper cryptographic security, use the bdRandomSeeded() function with a call to a
secure RNG function that you trust.
*/
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#ifndef BIGDRAND_H_
#define BIGDRAND_H_ 1
#include "bigd.h"
#include "bigdRand.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Generate a single random digit using internal RNG. */
bdigit_t bdRandDigit(void);
/** Generate a random BIGD number of bit length at most \c nbits using internal RNG
@param[out] a to receive generated random number
@param[in] nbits maximum number of bits
@returns Number of digits actually set
*/
size_t bdRandomBits(BIGD a, size_t nbits);
/* Added in [v2.4] */
/** Generate array of random octets (bytes) using internal RNG
* @remarks This function is in the correct form for BD_RANDFUNC.
*/
int bdRandomOctets(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen);
/** Generate a number at random from a uniform distribution in [0, n-1] */
size_t bdRandomNumber(BIGD a, BIGD n);
#ifdef __cplusplus
}
#endif
#endif /* BIGDRAND_H_ */
/* $Id: bigdRand.h $ */
/** @file
Interface for BigDigits "bd" random number functions using a "pretty-good" internal RNG
@par The internal random number generator (RNG)
The internal RNG uses a variant of the random number generation algorithm
in Appendix A of ANSI X9.31-1998, but using the Tiny Encryption Algorithm (TEAX)
instead of the Data Encryption Algorithm (DEA).
It uses the current time and process ID as a seed.
Although not strictly crypto secure, it is "pretty good", and certainly much better than
anything using the built-in rand() function in C. Look at the source code and make your own call.
@par
If you want proper cryptographic security, use the bdRandomSeeded() function with a call to a
secure RNG function that you trust.
*/
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#ifndef BIGDRAND_H_
#define BIGDRAND_H_ 1
#include "bigd.h"
#include "bigdRand.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Generate a single random digit using internal RNG. */
bdigit_t bdRandDigit(void);
/** Generate a random BIGD number of bit length at most \c nbits using internal RNG
@param[out] a to receive generated random number
@param[in] nbits maximum number of bits
@returns Number of digits actually set
*/
size_t bdRandomBits(BIGD a, size_t nbits);
/* Added in [v2.4] */
/** Generate array of random octets (bytes) using internal RNG
* @remarks This function is in the correct form for BD_RANDFUNC.
*/
int bdRandomOctets(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen);
/** Generate a number at random from a uniform distribution in [0, n-1] */
size_t bdRandomNumber(BIGD a, BIGD n);
#ifdef __cplusplus
}
#endif
#endif /* BIGDRAND_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,318 +1,318 @@
/* $Id: bigdigitsRand.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "bigdigits.h"
#include "bigdigitsRand.h"
static uint32_t btrrand(void);
/**********************/
/* EXPORTED FUNCTIONS */
/**********************/
DIGIT_T spBetterRand(void)
{ /* Returns a "better" pseudo-random digit. */
return (DIGIT_T)btrrand();
}
/* Added [v2.2] */
size_t mpRandomBits(DIGIT_T a[], size_t ndigits, size_t nbits)
/* Generate a random mp number <= 2^{nbits}-1 using internal RNG */
{
const int bits_per_digit = BITS_PER_DIGIT;
size_t i;
int j;
DIGIT_T r;
mpSetZero(a, ndigits);
r = spBetterRand();
j = bits_per_digit;
for (i = 0; i < nbits; i++)
{
if (j <= 0)
{
r = spBetterRand();
j = bits_per_digit;
}
mpSetBit(a, ndigits, i, r & 0x1);
r >>= 1;
j--;
}
return i;
}
/** Generate array of random octets (bytes) using internal RNG.
This function is in the correct form for BD_RANDFUNC.
Seed is ignored here.
*/
int mpRandomOctets(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen)
{
const int octets_per_digit = sizeof(DIGIT_T);
size_t i;
int j;
DIGIT_T r;
r = spBetterRand();
j = octets_per_digit;
for (i = 0; i < nbytes; i++)
{
if (j <= 0)
{
r = spBetterRand();
j = octets_per_digit;
}
bytes[i] = r & 0xFF;
r >>= 8;
j--;
}
return (int)i;
}
/**********************/
/* INTERNAL FUNCTIONS */
/**********************/
/******************************************************************************
Generates a pseudo-random DIGIT value using the generator algorithm from
ANSI X9.31 Appendix A.2.4 "Generating Pseudo Random Numbers Using the DEA"
(formerly ANSI X9.17, Appendix C) but with the `Tiny Encryption Algorithm` (TEAX)
replacing the `DES E-D-E two-key triple-encryption` algorithm (Double DES)
This variant has much less code, and is faster.
CAUTION: not thread-safe as it uses a static variable.
This is "pretty good", but not quite cryptographically secure since the seed is
only generated from the current time and process ID.
However, it is much better than just using the plain-old-rand() function.
The output should always pass the FIPS 140-2 statistical test.
Users can make their own call as to the security of this approach.
It's certainly sufficient for generating random digits for tests.
******************************************************************************/
/******************************************************************************
ANSI X9.17/X9.31 ALGORITHM:
Given
* D, a 64-bit representation of the current date-time
* S, a secret 64-bit seed that will be updated by this process
* K, a secret encryption key
Step 1. Compute the 64-bit block X = G(S, K, D) as follows:
1. I = E(D, K)
2. X = E(I XOR S, K)
3. S' = E(X XOR I, K)
where E(p, K) is the encryption of the 64-bit block p using key K.
Step 2. Return X and set S = S' for the next cycle.
******************************************************************************
THIS VARIANT:
1. Replace `Double DES` algorithm with `TEAX`.
2. Replace effective 112-bit Double DES key with 128-bit TEAX key.
******************************************************************************/
#define KEY_WORDS 4
static void encipher(uint32_t *const v,uint32_t *const w, const uint32_t *const k);
/* CAUTION: We use a static structure to store our values in. */
static struct {
int seeded;
uint32_t seed[2];
uint32_t key[KEY_WORDS];
} m_generator;
#if !(defined(ONLY_ANSI)) && (defined(_WIN32) || defined(WIN32))
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#elif !(defined(ONLY_ANSI)) && (defined(unix) || defined (linux) || defined(__linux))
#else
#endif
/* Cross-platform ways to get a 64-bit time value and the process ID */
#if defined(unix) || defined(__unix__) || defined(linux) || defined(__linux__)
static void get_time64(uint32_t t[2])
{
#include <sys/time.h>
struct timeval tv;
gettimeofday(&tv, NULL);
memcpy(t, &tv, 2*sizeof(uint32_t));
}
#include <unistd.h>
#define processid getpid
#elif defined(_WIN32) || defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static void get_time64(uint32_t t[2])
{
FILETIME ft;
GetSystemTimeAsFileTime (&ft);
t[0] = ft.dwHighDateTime;
t[1] = ft.dwLowDateTime;
}
#define processid GetCurrentProcessId
#else /* ANSI FALLBACK */
static void get_time64(uint32_t t[2])
{
/* Best we can do with strict ANSI */
/* [v2.2] added clock() as well as time() to improve precision.
* OK, so this isn't actually the time, but it's an independent value accurate to
* one millisecond, which is what we want.
*/
t[0] = (uint32_t)time(NULL);
t[1] = (uint32_t)clock();
}
unsigned long processid(void)
{ return 0; }
#endif
/* Given a 32-bit random seed, create a 64-bit seed S and 128-bit key K for the global generator */
static void btrseed(uint32_t seed)
{
int i;
uint32_t t[2];
/* Use plain old rand function to generate our global 64-bit seed S and initial 128-bit key K_0 */
srand(seed);
/* Only trust the lowest 8 bits from rand()... */
for (i = 0; i < 2; i++)
m_generator.seed[i] = (rand()&0xFF)<<24|(rand()&0xFF)<<16|(rand()&0xFF)<<8|(rand()&0xFF);
for (i = 0; i < KEY_WORDS; i++)
m_generator.key[i] = (rand()&0xFF)<<24|(rand()&0xFF)<<16|(rand()&0xFF)<<8|(rand()&0xFF);
/* Set flag so we only do this once */
m_generator.seeded = 1;
/* [v2.4] Blend in the current 64-bit time and re-encrypt the key with itself */
/* Note that the `block` in E(block, key) is 64 bits, but the `key` is 128 bits */
/* T = E(time, K_0) -- encrypt 64-bit time using K_0 */
get_time64(t);
encipher(t, t, m_generator.key);
/* K_1[0..63] = E(T XOR K_0[0..63], K_0)
-- encrypt left 64 bits of K_0 using K_0 --> left 64 bits of K_1
-- right 64 bits of K_0 --> right 64 bits of K_1 */
m_generator.key[0] ^= t[0];
m_generator.key[1] ^= t[1];
encipher(&m_generator.key[0], &m_generator.key[0], m_generator.key);
/* K_2[64..127] = E(T XOR K_1[64..127], K_1)
-- encrypt right 64 bits of K_1 using K_1 --> right 64 bits of K_2
-- left 64 bits of K_! --> left 64 bits of K_2 */
m_generator.key[2] ^= t[0];
m_generator.key[3] ^= t[1];
encipher(&m_generator.key[2], &m_generator.key[2], m_generator.key);
/* Output global key K = K_2 */
}
static uint32_t btrrand(void)
/* Returns one 32-bit word */
{
uint32_t inter[2], x[2];
/* Set seed if not already seeded */
if (!m_generator.seeded)
{ /* [v2.4] added process ID so processes launched at same time should give different values */
btrseed((uint32_t)time(NULL)<<16 ^ ((uint32_t)clock()<<8) ^ (uint32_t)processid());
}
/* I = E(D, K) */
get_time64(inter);
encipher(inter, inter, m_generator.key);
/* X = E(I XOR S, K) */
x[0] = inter[0] ^ m_generator.seed[0];
x[1] = inter[1] ^ m_generator.seed[1];
encipher(x, x, m_generator.key);
/* S' = E(X XOR I, K) */
inter[0] ^= x[0];
inter[1] ^= x[1];
encipher(inter, m_generator.seed, m_generator.key);
return x[0];
}
/************************************************
The Tiny Encryption Algorithm (TEA) by
David Wheeler and Roger Needham of the
Cambridge Computer Laboratory.
Placed in the Public Domain by
David Wheeler and Roger Needham.
**** ANSI C VERSION (New Variant) ****
Notes:
TEA is a Feistel cipher with XOR and
and addition as the non-linear mixing
functions.
Takes 64 bits of data in v[0] and v[1].
Returns 64 bits of data in w[0] and w[1].
Takes 128 bits of key in k[0] - k[3].
TEA can be operated in any of the modes
of DES. Cipher Block Chaining is, for example,
simple to implement.
n is the number of iterations. 32 is ample,
16 is sufficient, as few as eight may be OK.
The algorithm achieves good dispersion after
six iterations. The iteration count can be
made variable if required.
Note this is optimised for 32-bit CPUs with
fast shift capabilities. It can very easily
be ported to assembly language on most CPUs.
delta is chosen to be the real part of (the
golden ratio Sqrt(5/4) - 1/2 ~ 0.618034
multiplied by 2^32).
This version has been amended to foil two
weaknesses identified by David A. Wagner
(daw@cs.berkeley.edu): 1) effective key
length of old-variant TEA was 126 not 128
bits 2) a related key attack was possible
although impractical.
************************************************/
static void encipher(uint32_t *const v,uint32_t *const w, const uint32_t *const k)
{
register uint32_t y=v[0],z=v[1],sum=0,delta=0x9E3779B9,n=32;
while(n-->0)
{
y+= (((z<<4) ^ (z>>5)) + z) ^ (sum + k[sum & 3]);
sum += delta;
z+= (((y<<4) ^ (y>>5)) + y) ^ (sum + k[sum>>11 & 3]);
}
w[0]=y; w[1]=z;
}
/* $Id: bigdigitsRand.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "bigdigits.h"
#include "bigdigitsRand.h"
static uint32_t btrrand(void);
/**********************/
/* EXPORTED FUNCTIONS */
/**********************/
DIGIT_T spBetterRand(void)
{ /* Returns a "better" pseudo-random digit. */
return (DIGIT_T)btrrand();
}
/* Added [v2.2] */
size_t mpRandomBits(DIGIT_T a[], size_t ndigits, size_t nbits)
/* Generate a random mp number <= 2^{nbits}-1 using internal RNG */
{
const int bits_per_digit = BITS_PER_DIGIT;
size_t i;
int j;
DIGIT_T r;
mpSetZero(a, ndigits);
r = spBetterRand();
j = bits_per_digit;
for (i = 0; i < nbits; i++)
{
if (j <= 0)
{
r = spBetterRand();
j = bits_per_digit;
}
mpSetBit(a, ndigits, i, r & 0x1);
r >>= 1;
j--;
}
return i;
}
/** Generate array of random octets (bytes) using internal RNG.
This function is in the correct form for BD_RANDFUNC.
Seed is ignored here.
*/
int mpRandomOctets(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen)
{
const int octets_per_digit = sizeof(DIGIT_T);
size_t i;
int j;
DIGIT_T r;
r = spBetterRand();
j = octets_per_digit;
for (i = 0; i < nbytes; i++)
{
if (j <= 0)
{
r = spBetterRand();
j = octets_per_digit;
}
bytes[i] = r & 0xFF;
r >>= 8;
j--;
}
return (int)i;
}
/**********************/
/* INTERNAL FUNCTIONS */
/**********************/
/******************************************************************************
Generates a pseudo-random DIGIT value using the generator algorithm from
ANSI X9.31 Appendix A.2.4 "Generating Pseudo Random Numbers Using the DEA"
(formerly ANSI X9.17, Appendix C) but with the `Tiny Encryption Algorithm` (TEAX)
replacing the `DES E-D-E two-key triple-encryption` algorithm (Double DES)
This variant has much less code, and is faster.
CAUTION: not thread-safe as it uses a static variable.
This is "pretty good", but not quite cryptographically secure since the seed is
only generated from the current time and process ID.
However, it is much better than just using the plain-old-rand() function.
The output should always pass the FIPS 140-2 statistical test.
Users can make their own call as to the security of this approach.
It's certainly sufficient for generating random digits for tests.
******************************************************************************/
/******************************************************************************
ANSI X9.17/X9.31 ALGORITHM:
Given
* D, a 64-bit representation of the current date-time
* S, a secret 64-bit seed that will be updated by this process
* K, a secret encryption key
Step 1. Compute the 64-bit block X = G(S, K, D) as follows:
1. I = E(D, K)
2. X = E(I XOR S, K)
3. S' = E(X XOR I, K)
where E(p, K) is the encryption of the 64-bit block p using key K.
Step 2. Return X and set S = S' for the next cycle.
******************************************************************************
THIS VARIANT:
1. Replace `Double DES` algorithm with `TEAX`.
2. Replace effective 112-bit Double DES key with 128-bit TEAX key.
******************************************************************************/
#define KEY_WORDS 4
static void encipher(uint32_t *const v,uint32_t *const w, const uint32_t *const k);
/* CAUTION: We use a static structure to store our values in. */
static struct {
int seeded;
uint32_t seed[2];
uint32_t key[KEY_WORDS];
} m_generator;
#if !(defined(ONLY_ANSI)) && (defined(_WIN32) || defined(WIN32))
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#elif !(defined(ONLY_ANSI)) && (defined(unix) || defined (linux) || defined(__linux))
#else
#endif
/* Cross-platform ways to get a 64-bit time value and the process ID */
#if defined(unix) || defined(__unix__) || defined(linux) || defined(__linux__)
static void get_time64(uint32_t t[2])
{
#include <sys/time.h>
struct timeval tv;
gettimeofday(&tv, NULL);
memcpy(t, &tv, 2*sizeof(uint32_t));
}
#include <unistd.h>
#define processid getpid
#elif defined(_WIN32) || defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static void get_time64(uint32_t t[2])
{
FILETIME ft;
GetSystemTimeAsFileTime (&ft);
t[0] = ft.dwHighDateTime;
t[1] = ft.dwLowDateTime;
}
#define processid GetCurrentProcessId
#else /* ANSI FALLBACK */
static void get_time64(uint32_t t[2])
{
/* Best we can do with strict ANSI */
/* [v2.2] added clock() as well as time() to improve precision.
* OK, so this isn't actually the time, but it's an independent value accurate to
* one millisecond, which is what we want.
*/
t[0] = (uint32_t)time(NULL);
t[1] = (uint32_t)clock();
}
unsigned long processid(void)
{ return 0; }
#endif
/* Given a 32-bit random seed, create a 64-bit seed S and 128-bit key K for the global generator */
static void btrseed(uint32_t seed)
{
int i;
uint32_t t[2];
/* Use plain old rand function to generate our global 64-bit seed S and initial 128-bit key K_0 */
srand(seed);
/* Only trust the lowest 8 bits from rand()... */
for (i = 0; i < 2; i++)
m_generator.seed[i] = (rand()&0xFF)<<24|(rand()&0xFF)<<16|(rand()&0xFF)<<8|(rand()&0xFF);
for (i = 0; i < KEY_WORDS; i++)
m_generator.key[i] = (rand()&0xFF)<<24|(rand()&0xFF)<<16|(rand()&0xFF)<<8|(rand()&0xFF);
/* Set flag so we only do this once */
m_generator.seeded = 1;
/* [v2.4] Blend in the current 64-bit time and re-encrypt the key with itself */
/* Note that the `block` in E(block, key) is 64 bits, but the `key` is 128 bits */
/* T = E(time, K_0) -- encrypt 64-bit time using K_0 */
get_time64(t);
encipher(t, t, m_generator.key);
/* K_1[0..63] = E(T XOR K_0[0..63], K_0)
-- encrypt left 64 bits of K_0 using K_0 --> left 64 bits of K_1
-- right 64 bits of K_0 --> right 64 bits of K_1 */
m_generator.key[0] ^= t[0];
m_generator.key[1] ^= t[1];
encipher(&m_generator.key[0], &m_generator.key[0], m_generator.key);
/* K_2[64..127] = E(T XOR K_1[64..127], K_1)
-- encrypt right 64 bits of K_1 using K_1 --> right 64 bits of K_2
-- left 64 bits of K_! --> left 64 bits of K_2 */
m_generator.key[2] ^= t[0];
m_generator.key[3] ^= t[1];
encipher(&m_generator.key[2], &m_generator.key[2], m_generator.key);
/* Output global key K = K_2 */
}
static uint32_t btrrand(void)
/* Returns one 32-bit word */
{
uint32_t inter[2], x[2];
/* Set seed if not already seeded */
if (!m_generator.seeded)
{ /* [v2.4] added process ID so processes launched at same time should give different values */
btrseed((uint32_t)time(NULL)<<16 ^ ((uint32_t)clock()<<8) ^ (uint32_t)processid());
}
/* I = E(D, K) */
get_time64(inter);
encipher(inter, inter, m_generator.key);
/* X = E(I XOR S, K) */
x[0] = inter[0] ^ m_generator.seed[0];
x[1] = inter[1] ^ m_generator.seed[1];
encipher(x, x, m_generator.key);
/* S' = E(X XOR I, K) */
inter[0] ^= x[0];
inter[1] ^= x[1];
encipher(inter, m_generator.seed, m_generator.key);
return x[0];
}
/************************************************
The Tiny Encryption Algorithm (TEA) by
David Wheeler and Roger Needham of the
Cambridge Computer Laboratory.
Placed in the Public Domain by
David Wheeler and Roger Needham.
**** ANSI C VERSION (New Variant) ****
Notes:
TEA is a Feistel cipher with XOR and
and addition as the non-linear mixing
functions.
Takes 64 bits of data in v[0] and v[1].
Returns 64 bits of data in w[0] and w[1].
Takes 128 bits of key in k[0] - k[3].
TEA can be operated in any of the modes
of DES. Cipher Block Chaining is, for example,
simple to implement.
n is the number of iterations. 32 is ample,
16 is sufficient, as few as eight may be OK.
The algorithm achieves good dispersion after
six iterations. The iteration count can be
made variable if required.
Note this is optimised for 32-bit CPUs with
fast shift capabilities. It can very easily
be ported to assembly language on most CPUs.
delta is chosen to be the real part of (the
golden ratio Sqrt(5/4) - 1/2 ~ 0.618034
multiplied by 2^32).
This version has been amended to foil two
weaknesses identified by David A. Wagner
(daw@cs.berkeley.edu): 1) effective key
length of old-variant TEA was 126 not 128
bits 2) a related key attack was possible
although impractical.
************************************************/
static void encipher(uint32_t *const v,uint32_t *const w, const uint32_t *const k)
{
register uint32_t y=v[0],z=v[1],sum=0,delta=0x9E3779B9,n=32;
while(n-->0)
{
y+= (((z<<4) ^ (z>>5)) + z) ^ (sum + k[sum & 3]);
sum += delta;
z+= (((y<<4) ^ (y>>5)) + y) ^ (sum + k[sum>>11 & 3]);
}
w[0]=y; w[1]=z;
}

View File

@ -1,56 +1,56 @@
/* $Id: bigdigitsRand.h $ */
/** @file
Interface for BigDigits "mp" random number functions using a "pretty-good" internal RNG
*/
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
/* [v2.2] changed name from spRandom to bigdigitsRand */
#ifndef BIGDIGITSRAND_H_
#define BIGDIGITSRAND_H_ 1
#include "bigdigits.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Returns a "better" pseudo-random digit using internal RNG. */
DIGIT_T spBetterRand(void);
/** Generate a random mp number of bit length at most \c nbits using internal RNG
@param[out] a to receive generated random number
@param[in] ndigits number of digits in a
@param[in] nbits maximum number of bits
@returns Number of digits actually set
*/
size_t mpRandomBits(DIGIT_T a[], size_t ndigits, size_t nbits);
/* Added in [v2.4] */
/** Generate array of random octets (bytes) using internal RNG
* @remarks This function is in the correct form for BD_RANDFUNC to use in bdRandomSeeded().
* \c seed is ignored. */
int mpRandomOctets(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen);
#ifdef __cplusplus
}
#endif
#endif /* BIGDIGITSRAND_H_ */
/* $Id: bigdigitsRand.h $ */
/** @file
Interface for BigDigits "mp" random number functions using a "pretty-good" internal RNG
*/
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
/* [v2.2] changed name from spRandom to bigdigitsRand */
#ifndef BIGDIGITSRAND_H_
#define BIGDIGITSRAND_H_ 1
#include "bigdigits.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Returns a "better" pseudo-random digit using internal RNG. */
DIGIT_T spBetterRand(void);
/** Generate a random mp number of bit length at most \c nbits using internal RNG
@param[out] a to receive generated random number
@param[in] ndigits number of digits in a
@param[in] nbits maximum number of bits
@returns Number of digits actually set
*/
size_t mpRandomBits(DIGIT_T a[], size_t ndigits, size_t nbits);
/* Added in [v2.4] */
/** Generate array of random octets (bytes) using internal RNG
* @remarks This function is in the correct form for BD_RANDFUNC to use in bdRandomSeeded().
* \c seed is ignored. */
int mpRandomOctets(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen);
#ifdef __cplusplus
}
#endif
#endif /* BIGDIGITSRAND_H_ */

View File

@ -1,303 +1,303 @@
/* spExtras.c */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#include <assert.h>
#include "bigdigits.h"
#include "spExtras.h"
int spModMult(DIGIT_T *a, DIGIT_T x, DIGIT_T y, DIGIT_T m)
{ /* Computes a = (x * y) mod m */
/* Calc p[2] = x * y */
DIGIT_T p[2];
spMultiply(p, x, y);
/* Then modulo */
*a = mpShortMod(p, m, 2);
return 0;
}
DIGIT_T spGcd_old(DIGIT_T x, DIGIT_T y)
{ /* Returns gcd(x, y) */
/* Ref: Schneier 2nd ed, p245 */
DIGIT_T g;
if (x + y == 0)
return 0; /* Error */
g = y;
while (x > 0)
{
g = x;
x = y % x;
y = g;
}
return g;
}
DIGIT_T spGcd(DIGIT_T a, DIGIT_T b)
{ /* Returns gcd(a, b) */
/* Ref: Cohen, Algorithm 1.3.5 (Binary GCD)
and Menezes, Algorithm 14.54 */
DIGIT_T r, t;
unsigned int k;
/* 1. [Reduce size once] */
if (a < b)
{ /* exchange a and b */
t = a;
a = b;
b = t;
}
if (0 == b)
{
return a;
}
r = a % b;
a = b;
b = r;
if (0 == b)
{
return a;
}
/* 2. [Compute power of 2] */
k = 0;
while (ISEVEN(a) && ISEVEN(b))
{
a >>= 1; /* a <-- a/2 */
b >>= 1; /* b <-- b/2 */
k++; /* g <-- 2g */
}
while (a != 0)
{
while (ISEVEN(a))
{
a >>= 1; /* a <-- a/2 until a is odd */
}
while (ISEVEN(b))
{
b >>= 1; /* b <-- a/2 until b is odd */
}
/* t <-- |a-b|/2 */
if (b > a)
t = (b - a) >> 1;
else
t = (a - b) >> 1;
/* If a >= b then a = t, otherwise b = t */
if (a >= b)
a = t;
else
b = t;
}
/* Output (2^k.b) */
return (b << k);
}
/* spIsPrime */
static DIGIT_T SMALL_PRIMES[] = { 2, 3, 5, 7, 11, 13, 17, 19 };
#define N_SMALL_PRIMES sizeof(SMALL_PRIMES)/sizeof(DIGIT_T)
int spIsPrime(DIGIT_T w, size_t t)
{ /* Returns true if w is a probable prime
Carries out t iterations
(Use t = 50 for DSS Standard)
*/
/* Uses Rabin-Miller Probabilistic Primality Test,
Ref: FIPS-186-2 Appendix 2.
Also Schneier 2nd ed p 260 & Knuth Vol 2, p 379
and ANSI 9.42-2003 Annex B.1.1.
*/
unsigned int i, j;
DIGIT_T m, a, b, z;
int failed;
/* First check for small primes */
for (i = 0; i < N_SMALL_PRIMES; i++)
{
if (w % SMALL_PRIMES[i] == 0)
return 0; /* Failed */
}
/* Now do Rabin-Miller */
/* Step 2. Find a and m where w = 1 + (2^a)m
m is odd and 2^a is largest power of 2 dividing w - 1 */
m = w - 1;
for (a = 0; ISEVEN(m); a++)
m >>= 1; /* Divide by 2 until m is odd */
/*
assert((1 << a) * m + 1 == w);
*/
for (i = 0; i < t; i++)
{
failed = 1; /* Assume fail unless passed in loop */
/* Step 3. Generate a random integer 1 < b < w */
/* [v2.1] changed to 1 < b < w-1 */
b = spSimpleRand(2, w - 2);
/*
assert(1 < b && b < w-1);
*/
/* Step 4. Set j = 0 and z = b^m mod w */
j = 0;
spModExp(&z, b, m, w);
do
{
/* Step 5. If j = 0 and z = 1, or if z = w - 1 */
if ((j == 0 && z == 1) || (z == w - 1))
{ /* Passes on this loop - go to Step 9 */
failed = 0;
break;
}
/* Step 6. If j > 0 and z = 1 */
if (j > 0 && z == 1)
{ /* Fails - go to Step 8 */
failed = 1;
break;
}
/* Step 7. j = j + 1. If j < a set z = z^2 mod w */
j++;
if (j < a)
spModMult(&z, z, z, w);
/* Loop: if j < a go to Step 5 */
} while (j < a);
if (failed)
{ /* Step 8. Not a prime - stop */
return 0;
}
} /* Step 9. Go to Step 3 until i >= n */
/* If got here, probably prime => success */
return 1;
}
/* spModExp */
/* Two alternative functions for spModExp */
int spModExpK(DIGIT_T *exp, DIGIT_T x,
DIGIT_T n, DIGIT_T d)
{ /* Computes exp = x^n mod d */
/* Ref: Knuth Vol 2 Ch 4.6.3 p 462 Algorithm A
*/
DIGIT_T y = 1; /* Step A1. Initialise */
while (n > 0)
{ /* Step A2. Halve N */
if (n & 0x1) /* If odd */
spModMult(&y, y, x, d); /* Step A3. Multiply Y by Z */
n >>= 1; /* Halve N */
if (n > 0) /* Step A4. N = 0? Y is answer */
spModMult(&x, x, x, d); /* Step A5. Square Z */
}
*exp = y;
return 0;
}
int spModExpB(DIGIT_T *exp, DIGIT_T x,
DIGIT_T e, DIGIT_T m)
{ /* Computes exp = x^e mod m */
/* Binary left-to-right method
*/
DIGIT_T mask;
DIGIT_T y; /* Temp variable */
/* Find most significant bit in e */
for (mask = HIBITMASK; mask > 0; mask >>= 1)
{
if (e & mask)
break;
}
y = x;
/* For j = k-2 downto 0 step -1 */
for (mask >>= 1; mask > 0; mask >>= 1)
{
spModMult(&y, y, y, m); /* Square */
if (e & mask)
spModMult(&y, y, x, m); /* Multiply */
}
*exp = y;
return 0;
}
int spModInv(DIGIT_T *inv, DIGIT_T u, DIGIT_T v)
{ /* Computes inv = u^(-1) mod v */
/* Ref: Knuth Algorithm X Vol 2 p 342
ignoring u2, v2, t2
and avoiding negative numbers
*/
DIGIT_T u1, u3, v1, v3, t1, t3, q, w;
int bIterations = 1;
int result;
/* Step X1. Initialise */
u1 = 1;
u3 = u;
v1 = 0;
v3 = v;
while (v3 != 0) /* Step X2. */
{ /* Step X3. */
q = u3 / v3; /* Divide and */
t3 = u3 % v3;
w = q * v1; /* "Subtract" */
t1 = u1 + w;
/* Swap */
u1 = v1;
v1 = t1;
u3 = v3;
v3 = t3;
bIterations = -bIterations;
}
if (bIterations < 0)
*inv = v - u1;
else
*inv = u1;
/* Make sure u3 = gcd(u,v) == 1 */
if (u3 != 1)
{
result = 1;
*inv = 0;
}
else
result = 0;
return result;
}
/* spExtras.c */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#include <assert.h>
#include "bigdigits.h"
#include "spExtras.h"
int spModMult(DIGIT_T *a, DIGIT_T x, DIGIT_T y, DIGIT_T m)
{ /* Computes a = (x * y) mod m */
/* Calc p[2] = x * y */
DIGIT_T p[2];
spMultiply(p, x, y);
/* Then modulo */
*a = mpShortMod(p, m, 2);
return 0;
}
DIGIT_T spGcd_old(DIGIT_T x, DIGIT_T y)
{ /* Returns gcd(x, y) */
/* Ref: Schneier 2nd ed, p245 */
DIGIT_T g;
if (x + y == 0)
return 0; /* Error */
g = y;
while (x > 0)
{
g = x;
x = y % x;
y = g;
}
return g;
}
DIGIT_T spGcd(DIGIT_T a, DIGIT_T b)
{ /* Returns gcd(a, b) */
/* Ref: Cohen, Algorithm 1.3.5 (Binary GCD)
and Menezes, Algorithm 14.54 */
DIGIT_T r, t;
unsigned int k;
/* 1. [Reduce size once] */
if (a < b)
{ /* exchange a and b */
t = a;
a = b;
b = t;
}
if (0 == b)
{
return a;
}
r = a % b;
a = b;
b = r;
if (0 == b)
{
return a;
}
/* 2. [Compute power of 2] */
k = 0;
while (ISEVEN(a) && ISEVEN(b))
{
a >>= 1; /* a <-- a/2 */
b >>= 1; /* b <-- b/2 */
k++; /* g <-- 2g */
}
while (a != 0)
{
while (ISEVEN(a))
{
a >>= 1; /* a <-- a/2 until a is odd */
}
while (ISEVEN(b))
{
b >>= 1; /* b <-- a/2 until b is odd */
}
/* t <-- |a-b|/2 */
if (b > a)
t = (b - a) >> 1;
else
t = (a - b) >> 1;
/* If a >= b then a = t, otherwise b = t */
if (a >= b)
a = t;
else
b = t;
}
/* Output (2^k.b) */
return (b << k);
}
/* spIsPrime */
static DIGIT_T SMALL_PRIMES[] = { 2, 3, 5, 7, 11, 13, 17, 19 };
#define N_SMALL_PRIMES sizeof(SMALL_PRIMES)/sizeof(DIGIT_T)
int spIsPrime(DIGIT_T w, size_t t)
{ /* Returns true if w is a probable prime
Carries out t iterations
(Use t = 50 for DSS Standard)
*/
/* Uses Rabin-Miller Probabilistic Primality Test,
Ref: FIPS-186-2 Appendix 2.
Also Schneier 2nd ed p 260 & Knuth Vol 2, p 379
and ANSI 9.42-2003 Annex B.1.1.
*/
unsigned int i, j;
DIGIT_T m, a, b, z;
int failed;
/* First check for small primes */
for (i = 0; i < N_SMALL_PRIMES; i++)
{
if (w % SMALL_PRIMES[i] == 0)
return 0; /* Failed */
}
/* Now do Rabin-Miller */
/* Step 2. Find a and m where w = 1 + (2^a)m
m is odd and 2^a is largest power of 2 dividing w - 1 */
m = w - 1;
for (a = 0; ISEVEN(m); a++)
m >>= 1; /* Divide by 2 until m is odd */
/*
assert((1 << a) * m + 1 == w);
*/
for (i = 0; i < t; i++)
{
failed = 1; /* Assume fail unless passed in loop */
/* Step 3. Generate a random integer 1 < b < w */
/* [v2.1] changed to 1 < b < w-1 */
b = spSimpleRand(2, w - 2);
/*
assert(1 < b && b < w-1);
*/
/* Step 4. Set j = 0 and z = b^m mod w */
j = 0;
spModExp(&z, b, m, w);
do
{
/* Step 5. If j = 0 and z = 1, or if z = w - 1 */
if ((j == 0 && z == 1) || (z == w - 1))
{ /* Passes on this loop - go to Step 9 */
failed = 0;
break;
}
/* Step 6. If j > 0 and z = 1 */
if (j > 0 && z == 1)
{ /* Fails - go to Step 8 */
failed = 1;
break;
}
/* Step 7. j = j + 1. If j < a set z = z^2 mod w */
j++;
if (j < a)
spModMult(&z, z, z, w);
/* Loop: if j < a go to Step 5 */
} while (j < a);
if (failed)
{ /* Step 8. Not a prime - stop */
return 0;
}
} /* Step 9. Go to Step 3 until i >= n */
/* If got here, probably prime => success */
return 1;
}
/* spModExp */
/* Two alternative functions for spModExp */
int spModExpK(DIGIT_T *exp, DIGIT_T x,
DIGIT_T n, DIGIT_T d)
{ /* Computes exp = x^n mod d */
/* Ref: Knuth Vol 2 Ch 4.6.3 p 462 Algorithm A
*/
DIGIT_T y = 1; /* Step A1. Initialise */
while (n > 0)
{ /* Step A2. Halve N */
if (n & 0x1) /* If odd */
spModMult(&y, y, x, d); /* Step A3. Multiply Y by Z */
n >>= 1; /* Halve N */
if (n > 0) /* Step A4. N = 0? Y is answer */
spModMult(&x, x, x, d); /* Step A5. Square Z */
}
*exp = y;
return 0;
}
int spModExpB(DIGIT_T *exp, DIGIT_T x,
DIGIT_T e, DIGIT_T m)
{ /* Computes exp = x^e mod m */
/* Binary left-to-right method
*/
DIGIT_T mask;
DIGIT_T y; /* Temp variable */
/* Find most significant bit in e */
for (mask = HIBITMASK; mask > 0; mask >>= 1)
{
if (e & mask)
break;
}
y = x;
/* For j = k-2 downto 0 step -1 */
for (mask >>= 1; mask > 0; mask >>= 1)
{
spModMult(&y, y, y, m); /* Square */
if (e & mask)
spModMult(&y, y, x, m); /* Multiply */
}
*exp = y;
return 0;
}
int spModInv(DIGIT_T *inv, DIGIT_T u, DIGIT_T v)
{ /* Computes inv = u^(-1) mod v */
/* Ref: Knuth Algorithm X Vol 2 p 342
ignoring u2, v2, t2
and avoiding negative numbers
*/
DIGIT_T u1, u3, v1, v3, t1, t3, q, w;
int bIterations = 1;
int result;
/* Step X1. Initialise */
u1 = 1;
u3 = u;
v1 = 0;
v3 = v;
while (v3 != 0) /* Step X2. */
{ /* Step X3. */
q = u3 / v3; /* Divide and */
t3 = u3 % v3;
w = q * v1; /* "Subtract" */
t1 = u1 + w;
/* Swap */
u1 = v1;
v1 = t1;
u3 = v3;
v3 = t3;
bIterations = -bIterations;
}
if (bIterations < 0)
*inv = v - u1;
else
*inv = u1;
/* Make sure u3 = gcd(u,v) == 1 */
if (u3 != 1)
{
result = 1;
*inv = 0;
}
else
result = 0;
return result;
}

View File

@ -1,55 +1,55 @@
/* spExtras.h */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* Interface to extra BigDigits "sp" functions that operate with single digits */
#ifndef SPEXTRAS_H_
#define SPEXTRAS_H_ 1
#include "bigdigits.h"
int spModMult(DIGIT_T *a, DIGIT_T x, DIGIT_T y, DIGIT_T m);
/* Computes a = (x * y) mod m */
int spModInv(DIGIT_T *inv, DIGIT_T u, DIGIT_T v);
/* Computes inv = u^-1 mod v */
DIGIT_T spGcd(DIGIT_T x, DIGIT_T y);
/* Returns gcd(x, y) */
int spIsPrime(DIGIT_T w, size_t t);
/* Returns true if w is a probable prime, else false; t tests */
/* int spModExp(DIGIT_T *exp, DIGIT_T x, DIGIT_T n, DIGIT_T d); */
/* Computes exp = x^n mod d */
/* Two alternatives for spModExp:
define USE_KNUTH_MODEXP before <spExtras.h> to use Knuth method,
otherwise defaults to use Binary left-to-right method */
#ifdef USE_KNUTH_MODEXP
#define spModExp spModExpK
#else
#define spModExp spModExpB
#endif /* USE_KNUTH_MODEXP */
int spModExpK(DIGIT_T *exp, DIGIT_T x, DIGIT_T n, DIGIT_T d);
int spModExpB(DIGIT_T *exp, DIGIT_T x, DIGIT_T n, DIGIT_T d);
#endif /* SPEXTRAS_H_ */
/* spExtras.h */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* Interface to extra BigDigits "sp" functions that operate with single digits */
#ifndef SPEXTRAS_H_
#define SPEXTRAS_H_ 1
#include "bigdigits.h"
int spModMult(DIGIT_T *a, DIGIT_T x, DIGIT_T y, DIGIT_T m);
/* Computes a = (x * y) mod m */
int spModInv(DIGIT_T *inv, DIGIT_T u, DIGIT_T v);
/* Computes inv = u^-1 mod v */
DIGIT_T spGcd(DIGIT_T x, DIGIT_T y);
/* Returns gcd(x, y) */
int spIsPrime(DIGIT_T w, size_t t);
/* Returns true if w is a probable prime, else false; t tests */
/* int spModExp(DIGIT_T *exp, DIGIT_T x, DIGIT_T n, DIGIT_T d); */
/* Computes exp = x^n mod d */
/* Two alternatives for spModExp:
define USE_KNUTH_MODEXP before <spExtras.h> to use Knuth method,
otherwise defaults to use Binary left-to-right method */
#ifdef USE_KNUTH_MODEXP
#define spModExp spModExpK
#else
#define spModExp spModExpB
#endif /* USE_KNUTH_MODEXP */
int spModExpK(DIGIT_T *exp, DIGIT_T x, DIGIT_T n, DIGIT_T d);
int spModExpB(DIGIT_T *exp, DIGIT_T x, DIGIT_T n, DIGIT_T d);
#endif /* SPEXTRAS_H_ */

View File

@ -1,75 +1,75 @@
/* $Id: t_bdCPP.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#include "bigd.h"
#include "bigdRand.h"
#include <iostream>
using namespace std;
int main()
{
int ver;
ver = bdVersion();
cout << "bdVersion = " << ver << "\n";
BIGD u, v, w;
/* Create new BIGD objects */
u = bdNew();
v = bdNew();
w = bdNew();
/* Compute 2 * 0xdeadbeefface */
bdSetShort(u, 2);
bdConvFromHex(v, "deadbeefface");
bdMultiply(w, u, v);
/* Display the result */
bdPrintHex("", u, " * ");
bdPrintHex("0x", v, " = ");
bdPrintHex("0x", w, "\n");
/* and again in decimal format */
bdPrintDecimal("", u, " * ");
bdPrintDecimal("", v, " = ");
bdPrintDecimal("", w, "\n");
/* Add with digit overflow */
/* ffffffff+ffffffff=00000001 fffffffe */
bdSetShort(u, 0xffffffff);
bdSetShort(v, 0xffffffff);
bdAdd(w, u, v);
bdPrintHex("", u, "+");
bdPrintHex("", v, "=");
bdPrintHex("", w, "\n");
/* Generate some random digits using internal RNG */
cout << "Some random numbers:\n";
bdSetShort(u, bdRandDigit());
bdPrintHex("short: ", u, "\n");
bdRandomBits(u, 512);
bdPrintHex("512 bits: ", u, "\n");
/* Free all objects we made */
bdFree(&u);
bdFree(&v);
bdFree(&w);
return 0;
}
/* $Id: t_bdCPP.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#include "bigd.h"
#include "bigdRand.h"
#include <iostream>
using namespace std;
int main()
{
int ver;
ver = bdVersion();
cout << "bdVersion = " << ver << "\n";
BIGD u, v, w;
/* Create new BIGD objects */
u = bdNew();
v = bdNew();
w = bdNew();
/* Compute 2 * 0xdeadbeefface */
bdSetShort(u, 2);
bdConvFromHex(v, "deadbeefface");
bdMultiply(w, u, v);
/* Display the result */
bdPrintHex("", u, " * ");
bdPrintHex("0x", v, " = ");
bdPrintHex("0x", w, "\n");
/* and again in decimal format */
bdPrintDecimal("", u, " * ");
bdPrintDecimal("", v, " = ");
bdPrintDecimal("", w, "\n");
/* Add with digit overflow */
/* ffffffff+ffffffff=00000001 fffffffe */
bdSetShort(u, 0xffffffff);
bdSetShort(v, 0xffffffff);
bdAdd(w, u, v);
bdPrintHex("", u, "+");
bdPrintHex("", v, "=");
bdPrintHex("", w, "\n");
/* Generate some random digits using internal RNG */
cout << "Some random numbers:\n";
bdSetShort(u, bdRandDigit());
bdPrintHex("short: ", u, "\n");
bdRandomBits(u, 512);
bdPrintHex("512 bits: ", u, "\n");
/* Free all objects we made */
bdFree(&u);
bdFree(&v);
bdFree(&w);
return 0;
}

View File

@ -1,182 +1,182 @@
/* $Id: t_bdDSA.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* EXAMPLE OF THE DSA from APPENDIX 5 FIPS PUB 186-2
"DIGITAL SIGNATURE STANDARD (DSS)", 27 January 2000 */
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <assert.h>
#include "bigd.h"
int main(void)
{
BIGD p, q, g;
BIGD x, k;
BIGD hashm;
BIGD k1, y, tmp;
BIGD r, s;
BIGD w, u1, u2, v, gg, yy;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
printf("EXAMPLE OF THE DSA from APPENDIX 5 FIPS PUB 186-2 'DIGITAL SIGNATURE STANDARD'\n");
/* Initialise variables */
p = bdNew();
q = bdNew();
g = bdNew();
x = bdNew();
k = bdNew();
k1 = bdNew();
y = bdNew();
tmp = bdNew();
hashm= bdNew();
r= bdNew();
s= bdNew();
w = bdNew();
u1 = bdNew();
u2 = bdNew();
v = bdNew();
gg = bdNew();
yy = bdNew();
/* INPUT */
/* Convert integers from hex format to BIGD (spaces are ignored) */
bdConvFromHex(p, "8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7"
"cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac"
"49693dfb f83724c2 ec0736ee 31c80291");
bdConvFromHex(q, "c773218c 737ec8ee 993b4f2d ed30f48e dace915f");
bdConvFromHex(g, "626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb"
"3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c"
"c42e9f6f 464b088c c572af53 e6d78802");
bdConvFromHex(x, "2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614");
bdConvFromHex(k, "358dad57 1462710f 50e254cf 1a376b2b deaadfbf");
/* M = ASCII form of "abc" (See FIPS PUB 180-1, Appendix A)
(SHA-1)(M) = <pre-computed value> */
bdConvFromHex(hashm, "a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
bdPrintHex("g=", g, "\n");
bdPrintHex("x=", x, "\n");
bdPrintHex("k=", k, "\n");
bdPrintHex("SHA-1(M)=", hashm, "\n");
/* COMPUTATION BY SIGNER */
/* (p, q, g) are public, common values
x is signer's private key
k is a random integer 0 < k < q
Keep (x, k) secret
*/
/* Compute k' = k^-1 mod q */
bdModInv(k1, k, q);
bdPrintHex("k^-1=", k1, "\n");
/* Compute y = g^x mod p */
bdModExp(y, g, x, p);
bdPrintHex("y=", y, "\n");
/* Compute r = (g^k mod p) mod q */
bdModExp(tmp, g, k, p);
bdModulo(r, tmp, q);
bdPrintHex("r=", r, "\n");
/* Compute s = (k^-1(SHA-1(M) + xr)) mod q */
bdModMult(tmp, x, r, q);
bdAdd(tmp, tmp, hashm);
bdModMult(s, k1, tmp, q);
bdPrintHex("s=", s, "\n");
/* VERIFICATION BY RECEIVER */
/* (p, q, g) are public, common values
y is signer's public key
(r,s) = signature(M)
Receiver receives (M', r', s').
Receiver recomputes SHA-1(M') for received message M'
*/
/* Check 0 < r' < q and 0 < s' < q */
assert(bdCompare(q, r) > 0);
assert(bdCompare(q, s) > 0);
/* Compute w = s^-1 mod q */
bdModInv(w, s, q);
bdPrintHex("w=", w, "\n");
/* Compute u1 = ((SHA-1(M'))w) mod q */
bdModMult(u1, hashm, w, q);
bdPrintHex("u1=", u1, "\n");
/* Compute u2 = ((r')w) mod q */
bdModMult(u2, r, w, q);
bdPrintHex("u2=", u2, "\n");
/* Compute g^u1 mod p */
bdModExp(gg, g, u1, p);
bdPrintHex("g^u1 mod p=\n", gg, "\n");
/* Compute y^u2 mod p */
bdModExp(yy, y, u2, p);
bdPrintHex("y^u2 mod p=\n", yy, "\n");
/* Compute v = (((g^u1)(y^u2)) mod p) mod q */
bdModMult(tmp, gg, yy, p);
bdModulo(v, tmp, q);
bdPrintHex("v=", v, "\n");
/* Verify that v = r' */
if (bdIsEqual(v, r))
printf("Signature verified OK\n");
else
printf("Signature verification FAILED!\n");
assert(bdIsEqual(v, r));
/* Clean up */
bdFree(&p);
bdFree(&q);
bdFree(&g);
bdFree(&x);
bdFree(&k);
bdFree(&k1);
bdFree(&y);
bdFree(&tmp);
bdFree(&hashm);
bdFree(&r);
bdFree(&s);
bdFree(&w);
bdFree(&u1);
bdFree(&u2);
bdFree(&v);
bdFree(&gg);
bdFree(&yy);
printf("OK, successfully completed tests.\n");
return 0;
}
/* $Id: t_bdDSA.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* EXAMPLE OF THE DSA from APPENDIX 5 FIPS PUB 186-2
"DIGITAL SIGNATURE STANDARD (DSS)", 27 January 2000 */
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <assert.h>
#include "bigd.h"
int main(void)
{
BIGD p, q, g;
BIGD x, k;
BIGD hashm;
BIGD k1, y, tmp;
BIGD r, s;
BIGD w, u1, u2, v, gg, yy;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
printf("EXAMPLE OF THE DSA from APPENDIX 5 FIPS PUB 186-2 'DIGITAL SIGNATURE STANDARD'\n");
/* Initialise variables */
p = bdNew();
q = bdNew();
g = bdNew();
x = bdNew();
k = bdNew();
k1 = bdNew();
y = bdNew();
tmp = bdNew();
hashm= bdNew();
r= bdNew();
s= bdNew();
w = bdNew();
u1 = bdNew();
u2 = bdNew();
v = bdNew();
gg = bdNew();
yy = bdNew();
/* INPUT */
/* Convert integers from hex format to BIGD (spaces are ignored) */
bdConvFromHex(p, "8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7"
"cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac"
"49693dfb f83724c2 ec0736ee 31c80291");
bdConvFromHex(q, "c773218c 737ec8ee 993b4f2d ed30f48e dace915f");
bdConvFromHex(g, "626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb"
"3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c"
"c42e9f6f 464b088c c572af53 e6d78802");
bdConvFromHex(x, "2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614");
bdConvFromHex(k, "358dad57 1462710f 50e254cf 1a376b2b deaadfbf");
/* M = ASCII form of "abc" (See FIPS PUB 180-1, Appendix A)
(SHA-1)(M) = <pre-computed value> */
bdConvFromHex(hashm, "a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
bdPrintHex("g=", g, "\n");
bdPrintHex("x=", x, "\n");
bdPrintHex("k=", k, "\n");
bdPrintHex("SHA-1(M)=", hashm, "\n");
/* COMPUTATION BY SIGNER */
/* (p, q, g) are public, common values
x is signer's private key
k is a random integer 0 < k < q
Keep (x, k) secret
*/
/* Compute k' = k^-1 mod q */
bdModInv(k1, k, q);
bdPrintHex("k^-1=", k1, "\n");
/* Compute y = g^x mod p */
bdModExp(y, g, x, p);
bdPrintHex("y=", y, "\n");
/* Compute r = (g^k mod p) mod q */
bdModExp(tmp, g, k, p);
bdModulo(r, tmp, q);
bdPrintHex("r=", r, "\n");
/* Compute s = (k^-1(SHA-1(M) + xr)) mod q */
bdModMult(tmp, x, r, q);
bdAdd(tmp, tmp, hashm);
bdModMult(s, k1, tmp, q);
bdPrintHex("s=", s, "\n");
/* VERIFICATION BY RECEIVER */
/* (p, q, g) are public, common values
y is signer's public key
(r,s) = signature(M)
Receiver receives (M', r', s').
Receiver recomputes SHA-1(M') for received message M'
*/
/* Check 0 < r' < q and 0 < s' < q */
assert(bdCompare(q, r) > 0);
assert(bdCompare(q, s) > 0);
/* Compute w = s^-1 mod q */
bdModInv(w, s, q);
bdPrintHex("w=", w, "\n");
/* Compute u1 = ((SHA-1(M'))w) mod q */
bdModMult(u1, hashm, w, q);
bdPrintHex("u1=", u1, "\n");
/* Compute u2 = ((r')w) mod q */
bdModMult(u2, r, w, q);
bdPrintHex("u2=", u2, "\n");
/* Compute g^u1 mod p */
bdModExp(gg, g, u1, p);
bdPrintHex("g^u1 mod p=\n", gg, "\n");
/* Compute y^u2 mod p */
bdModExp(yy, y, u2, p);
bdPrintHex("y^u2 mod p=\n", yy, "\n");
/* Compute v = (((g^u1)(y^u2)) mod p) mod q */
bdModMult(tmp, gg, yy, p);
bdModulo(v, tmp, q);
bdPrintHex("v=", v, "\n");
/* Verify that v = r' */
if (bdIsEqual(v, r))
printf("Signature verified OK\n");
else
printf("Signature verification FAILED!\n");
assert(bdIsEqual(v, r));
/* Clean up */
bdFree(&p);
bdFree(&q);
bdFree(&g);
bdFree(&x);
bdFree(&k);
bdFree(&k1);
bdFree(&y);
bdFree(&tmp);
bdFree(&hashm);
bdFree(&r);
bdFree(&s);
bdFree(&w);
bdFree(&u1);
bdFree(&u2);
bdFree(&v);
bdFree(&gg);
bdFree(&yy);
printf("OK, successfully completed tests.\n");
return 0;
}

View File

@ -1,65 +1,65 @@
/* $Id: t_bdQuickRandBits.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
/*
What is the difference between bdQuickRandBits and bdRandomBits?
bdRandomBits() uses the "pretty-good" internal RNG and requires you to include bigdRand.h
and compile with bigdRand.c and bigdigitsRand.c.
You can be pretty sure that the numbers generated will pass all statistical tests for randomness.
bdQuickRandBits() just needs the standard bigd.h include file and you do not need to
add the modules bigdRand.c and bigdigitsRand.c to your project.
It uses the stdlib rand() function, which is by no means secure, but it will quickly fill up a number
with the required number of random-looking bits.
It might repeat if you call twice in quick succession. It's quick and dirty, as advertised.
If you *really* want a secure random number, then use bdRandomSeeded() and call your own super-secure
random number generator, throwing in your own bit of extra entropy with the seed.
*/
#include <stdio.h>
#include <assert.h>
#include "bigd.h"
#include "bigdRand.h"
int main(void)
{
BIGD a;
int i;
/* $Id: t_bdQuickRandBits.c $ */
a = bdNew();
// Test bdQuickRandBits (quick-and-dirty)
printf("Testing bdQuickRandBits...\n");
for (i = 0; i < 10; i++)
{
bdQuickRandBits(a, 128);
bdPrintHex("", a, "\n");
}
// Test bdRandomBits (more secure)
printf("Testing bdRandomBits...\n");
for (i = 0; i < 10; i++)
{
bdRandomBits(a, 128);
bdPrintHex("", a, "\n");
}
return 0;
}
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
/*
What is the difference between bdQuickRandBits and bdRandomBits?
bdRandomBits() uses the "pretty-good" internal RNG and requires you to include bigdRand.h
and compile with bigdRand.c and bigdigitsRand.c.
You can be pretty sure that the numbers generated will pass all statistical tests for randomness.
bdQuickRandBits() just needs the standard bigd.h include file and you do not need to
add the modules bigdRand.c and bigdigitsRand.c to your project.
It uses the stdlib rand() function, which is by no means secure, but it will quickly fill up a number
with the required number of random-looking bits.
It might repeat if you call twice in quick succession. It's quick and dirty, as advertised.
If you *really* want a secure random number, then use bdRandomSeeded() and call your own super-secure
random number generator, throwing in your own bit of extra entropy with the seed.
*/
#include <stdio.h>
#include <assert.h>
#include "bigd.h"
#include "bigdRand.h"
int main(void)
{
BIGD a;
int i;
a = bdNew();
// Test bdQuickRandBits (quick-and-dirty)
printf("Testing bdQuickRandBits...\n");
for (i = 0; i < 10; i++)
{
bdQuickRandBits(a, 128);
bdPrintHex("", a, "\n");
}
// Test bdRandomBits (more secure)
printf("Testing bdRandomBits...\n");
for (i = 0; i < 10; i++)
{
bdRandomBits(a, 128);
bdPrintHex("", a, "\n");
}
return 0;
}

View File

@ -1,220 +1,220 @@
/* $Id: t_bdRDSA.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* EXAMPLE OF THE rDSA from ANSI X9.31 -1998
Digital Signatures Using Reversible Public Key
Cryptography for the Financial Services Industry (rDSA),
September 9, 1998
Appendix D.1 Odd e = 3 with 1024-bit n
and D.3 Odd e =3 with 2048-bit n
*/
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <assert.h>
#include "bigd.h"
int rDSA_SignAndVerify(BIGD ir, BIGD n, BIGD e, BIGD d)
{
BIGD s;
BIGD tmp;
BIGD rr, ir1, rr1;
int result;
/* Initialise variables */
s = bdNew();
rr = bdNew();
ir1 = bdNew();
rr1 = bdNew();
tmp = bdNew();
bdPrintHex("n=\n", n, "\n");
bdPrintHex("e=", e, "\n");
bdPrintHex("d=\n", d, "\n");
bdPrintHex("IR=\n", ir, "\n");
/* COMPUTATION BY SIGNER */
/* (n, e) is the public key
(n, d) is the private key
IR is the encoded message
Keep d secret
*/
/* For odd e, RR = IR. The value RR^d mod n is now computed */
bdModExp(tmp, ir, d, n);
bdPrintHex("RR^d mod n=\n", tmp, "\n");
/* S = min { RR^d mod n, n-(RR^d mod n) } */
/* i.e. if this value > n/2, the signature S = n - (RR^d mod n) */
bdSubtract(s, n, tmp);
if (bdCompare(s, tmp) > 0)
bdSetEqual(s, tmp);
bdPrintHex("S=\n", s, "\n");
/* D.1.3 Signature Verification */
/* The value (S')^e mod n is computed to yield RR'. */
bdModExp(rr, s, e, n);
bdPrintHex("RR'=\n", rr, "\n");
/* If RR' = 12 mod 16, then IR' = RR';
If n - RR' = 12 mod 16, then IR' = n - RR'; */
if (bdShortMod(tmp, rr, 16) == 12)
bdSetEqual(ir1, rr);
else
bdSubtract(ir1, n, rr);
bdPrintHex("IR'=\n", ir1, "\n");
/* Since IR' is identical to the computed hash IR, and the signature verification is
successful. */
result = bdIsEqual(ir1, ir);
if (result)
printf("Signature verified OK\n");
else
printf("Signature verification FAILED!\n");
/* Clean up */
bdFree(&s);
bdFree(&rr);
bdFree(&ir1);
bdFree(&rr1);
bdFree(&tmp);
return result; /* TRUE = success */
}
int main(void)
{
BIGD e, n, d;
BIGD ir;
int result;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
printf("EXAMPLE OF THE rDSA from ANSI X9.31-1998 Appendix D\n");
/* Initialise variables */
e = bdNew();
n = bdNew();
d = bdNew();
ir = bdNew();
/* INPUT */
/* Convert integers from hex format to BIGD (spaces are ignored) */
bdConvFromHex(n, "ACD1CC46 DFE54FE8 F9786672 664CA269 0D0AD7E5"
"003BC642 7954D939 EEE8B271 52E6A947 450D7FA9"
"80172DE0 64D6569A 28A83FE7 0FA840F5 E9802CB8"
"984AB34B D5C1E639 9EC21E4D 3A3A69BE 4E676F39"
"5AAFEF7C 4925FD4F AEE9F9E5 E48AF431 5DF0EC2D"
"B9AD7A35 0B3DF2F4 D15DC003 9846D1AC A3527B1A"
"75049E3F E34F43BD");
bdConvFromHex(d, "1CCDA20B CFFB8D51 7EE96668 66621B11 822C7950"
"D55F4BB5 BEE37989 A7D17312 E326718B E0D79546"
"EAAE87A5 6623B919 B1715FFB D7F16028 FC400774"
"1961C88C 5D7B4DAA AC8D36A9 8C9EFBB2 6C8A4A0E"
"6BC15B35 8E528A1A C9D0F042 BEB93BCA 16B541B3"
"3F80C933 A3B76928 5C462ED5 677BFE89 DF07BED5"
"C127FD13 241D3C4B");
bdConvFromHex(ir, "6BBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBAA999 3E364706 816ABA3E 25717850"
"C26C9CD0 D89D33CC");
/* Set e = 3 directly */
bdSetShort(e, 3);
result = rDSA_SignAndVerify(ir, n, e, d);
assert(result);
/* Repeat for D.3 Odd e =3 with 2048-bit n */
bdConvFromHex(n, "BCCA30CA 5280BC51 E758DBAF FEDFE46A 5D2A78D8"
"3969E154 780F9B27 AD4E76E6 3E8FA960 29C04DE3"
"F2C4B01F ECBEBB44 FC2F5F8A C69BD0E3 278FF065"
"8A6F9AC2 3BCFB2C9 AAAF1AC4 D5571A55 D3B1EC35"
"50CF34D8 F789235D D3B5C4E2 F3DF1761 19D918F2"
"D35E805B 62FC35FE E5FD0785 4824B984 6DC1665E"
"35A31873 BF6A24FE 50842D0A A0305C35 D0F45B0D"
"7C2F1E94 32D850D6 7956D383 BBEF52FC 2ACBF7AE"
"6F7CA214 88A56456 BDF66726 96EE037C 3CAA2199"
"904E37AA 40134E10 155FC813 93A225BD 129C4B3B"
"C91AD3A5 FC958A6A BCABE355 0390B677 87625D78"
"F8D3172B 673C4482 CE354B89 51D7E8C4 DDCE5D4C"
"DFA6790C 6CE8C02C 8D807AE2 6F27FE33");
bdConvFromHex(d, "7DDC2086 E1AB2836 9A3B3D1F FF3FED9C 3E1C5090"
"26469638 500A676F C8DEF9EE D45FC640 1BD58942"
"A1D8756A 9DD47CD8 A81F9507 2F128B42 1A5FF599"
"06F511D6 D28A7731 1C74BC83 38E4BC39 37CBF2CE"
"35DF7890 A5061793 E2792DEC A294BA40 BBE610A1"
"E23F003C ECA823FF 43FE0503 856DD102 F3D6443E"
"CE6CBAF7 D4F16DFD BAF7C2F8 CB4955E2 F2DF29FD"
"A7A4DD7B 93785252 E2CA4AAD 14E8B1A1 7881D381"
"DAD9061E C8AB50DD CBF8B56A FA464F01 D28DFDFF"
"0CAFF6B5 588E8F77 6FA128DE 7C102494 7D5D8067"
"3F545A5C 73FBC16B 609A33A1 1021DD8F 37A4E7C4"
"78AA19E3 BCB1BBD8 F4AA9232 65F1F1D5 5236753A"
"C8C10D60 F0FAB073 66439A90 5E2C63AB");
bdConvFromHex(ir, "6BBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBAA999 3E364706"
"816ABA3E 25717850 C26C9CD0 D89D33CC");
result = rDSA_SignAndVerify(ir, n, e, d);
assert(result);
/* Clean up */
bdFree(&e);
bdFree(&n);
bdFree(&d);
bdFree(&ir);
printf("OK, successfully completed tests.\n");
return 0;
}
/* $Id: t_bdRDSA.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* EXAMPLE OF THE rDSA from ANSI X9.31 -1998
Digital Signatures Using Reversible Public Key
Cryptography for the Financial Services Industry (rDSA),
September 9, 1998
Appendix D.1 Odd e = 3 with 1024-bit n
and D.3 Odd e =3 with 2048-bit n
*/
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <assert.h>
#include "bigd.h"
int rDSA_SignAndVerify(BIGD ir, BIGD n, BIGD e, BIGD d)
{
BIGD s;
BIGD tmp;
BIGD rr, ir1, rr1;
int result;
/* Initialise variables */
s = bdNew();
rr = bdNew();
ir1 = bdNew();
rr1 = bdNew();
tmp = bdNew();
bdPrintHex("n=\n", n, "\n");
bdPrintHex("e=", e, "\n");
bdPrintHex("d=\n", d, "\n");
bdPrintHex("IR=\n", ir, "\n");
/* COMPUTATION BY SIGNER */
/* (n, e) is the public key
(n, d) is the private key
IR is the encoded message
Keep d secret
*/
/* For odd e, RR = IR. The value RR^d mod n is now computed */
bdModExp(tmp, ir, d, n);
bdPrintHex("RR^d mod n=\n", tmp, "\n");
/* S = min { RR^d mod n, n-(RR^d mod n) } */
/* i.e. if this value > n/2, the signature S = n - (RR^d mod n) */
bdSubtract(s, n, tmp);
if (bdCompare(s, tmp) > 0)
bdSetEqual(s, tmp);
bdPrintHex("S=\n", s, "\n");
/* D.1.3 Signature Verification */
/* The value (S')^e mod n is computed to yield RR'. */
bdModExp(rr, s, e, n);
bdPrintHex("RR'=\n", rr, "\n");
/* If RR' = 12 mod 16, then IR' = RR';
If n - RR' = 12 mod 16, then IR' = n - RR'; */
if (bdShortMod(tmp, rr, 16) == 12)
bdSetEqual(ir1, rr);
else
bdSubtract(ir1, n, rr);
bdPrintHex("IR'=\n", ir1, "\n");
/* Since IR' is identical to the computed hash IR, and the signature verification is
successful. */
result = bdIsEqual(ir1, ir);
if (result)
printf("Signature verified OK\n");
else
printf("Signature verification FAILED!\n");
/* Clean up */
bdFree(&s);
bdFree(&rr);
bdFree(&ir1);
bdFree(&rr1);
bdFree(&tmp);
return result; /* TRUE = success */
}
int main(void)
{
BIGD e, n, d;
BIGD ir;
int result;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
printf("EXAMPLE OF THE rDSA from ANSI X9.31-1998 Appendix D\n");
/* Initialise variables */
e = bdNew();
n = bdNew();
d = bdNew();
ir = bdNew();
/* INPUT */
/* Convert integers from hex format to BIGD (spaces are ignored) */
bdConvFromHex(n, "ACD1CC46 DFE54FE8 F9786672 664CA269 0D0AD7E5"
"003BC642 7954D939 EEE8B271 52E6A947 450D7FA9"
"80172DE0 64D6569A 28A83FE7 0FA840F5 E9802CB8"
"984AB34B D5C1E639 9EC21E4D 3A3A69BE 4E676F39"
"5AAFEF7C 4925FD4F AEE9F9E5 E48AF431 5DF0EC2D"
"B9AD7A35 0B3DF2F4 D15DC003 9846D1AC A3527B1A"
"75049E3F E34F43BD");
bdConvFromHex(d, "1CCDA20B CFFB8D51 7EE96668 66621B11 822C7950"
"D55F4BB5 BEE37989 A7D17312 E326718B E0D79546"
"EAAE87A5 6623B919 B1715FFB D7F16028 FC400774"
"1961C88C 5D7B4DAA AC8D36A9 8C9EFBB2 6C8A4A0E"
"6BC15B35 8E528A1A C9D0F042 BEB93BCA 16B541B3"
"3F80C933 A3B76928 5C462ED5 677BFE89 DF07BED5"
"C127FD13 241D3C4B");
bdConvFromHex(ir, "6BBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBAA999 3E364706 816ABA3E 25717850"
"C26C9CD0 D89D33CC");
/* Set e = 3 directly */
bdSetShort(e, 3);
result = rDSA_SignAndVerify(ir, n, e, d);
assert(result);
/* Repeat for D.3 Odd e =3 with 2048-bit n */
bdConvFromHex(n, "BCCA30CA 5280BC51 E758DBAF FEDFE46A 5D2A78D8"
"3969E154 780F9B27 AD4E76E6 3E8FA960 29C04DE3"
"F2C4B01F ECBEBB44 FC2F5F8A C69BD0E3 278FF065"
"8A6F9AC2 3BCFB2C9 AAAF1AC4 D5571A55 D3B1EC35"
"50CF34D8 F789235D D3B5C4E2 F3DF1761 19D918F2"
"D35E805B 62FC35FE E5FD0785 4824B984 6DC1665E"
"35A31873 BF6A24FE 50842D0A A0305C35 D0F45B0D"
"7C2F1E94 32D850D6 7956D383 BBEF52FC 2ACBF7AE"
"6F7CA214 88A56456 BDF66726 96EE037C 3CAA2199"
"904E37AA 40134E10 155FC813 93A225BD 129C4B3B"
"C91AD3A5 FC958A6A BCABE355 0390B677 87625D78"
"F8D3172B 673C4482 CE354B89 51D7E8C4 DDCE5D4C"
"DFA6790C 6CE8C02C 8D807AE2 6F27FE33");
bdConvFromHex(d, "7DDC2086 E1AB2836 9A3B3D1F FF3FED9C 3E1C5090"
"26469638 500A676F C8DEF9EE D45FC640 1BD58942"
"A1D8756A 9DD47CD8 A81F9507 2F128B42 1A5FF599"
"06F511D6 D28A7731 1C74BC83 38E4BC39 37CBF2CE"
"35DF7890 A5061793 E2792DEC A294BA40 BBE610A1"
"E23F003C ECA823FF 43FE0503 856DD102 F3D6443E"
"CE6CBAF7 D4F16DFD BAF7C2F8 CB4955E2 F2DF29FD"
"A7A4DD7B 93785252 E2CA4AAD 14E8B1A1 7881D381"
"DAD9061E C8AB50DD CBF8B56A FA464F01 D28DFDFF"
"0CAFF6B5 588E8F77 6FA128DE 7C102494 7D5D8067"
"3F545A5C 73FBC16B 609A33A1 1021DD8F 37A4E7C4"
"78AA19E3 BCB1BBD8 F4AA9232 65F1F1D5 5236753A"
"C8C10D60 F0FAB073 66439A90 5E2C63AB");
bdConvFromHex(ir, "6BBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB"
"BBBBBBBB BBBBBBBB BBBBBBBB BBBAA999 3E364706"
"816ABA3E 25717850 C26C9CD0 D89D33CC");
result = rDSA_SignAndVerify(ir, n, e, d);
assert(result);
/* Clean up */
bdFree(&e);
bdFree(&n);
bdFree(&d);
bdFree(&ir);
printf("OK, successfully completed tests.\n");
return 0;
}

View File

@ -1,454 +1,454 @@
/* $Id: t_bdRSA.c $ */
/* Test BigDigits "bd" functions using a new RSA key and random data */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "bigd.h"
static int my_rand(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen)
/* Our own (very insecure) random generator func using good old rand()
but in the required format for BD_RANDFUNC
-- replace this in practice with your own cryptographically-secure function
-- or use bdRandomOctets() in bigdRand.h
*/
{
unsigned int myseed;
size_t i;
int offset;
/* Use time for 32-bit seed - then blend in user-supplied seed, if any */
myseed = (unsigned)time(NULL) ^ (unsigned)clock();
if (seed)
{
for (offset = 0, i = 0; i < seedlen; i++, offset = (offset + 1) % sizeof(unsigned))
myseed ^= ((unsigned int)seed[i] << (offset * 8));
}
srand(myseed);
while (nbytes--)
{
*bytes++ = rand() & 0xFF;
}
return 0;
}
#define give_a_sign(c) putchar((c))
static bdigit_t SMALL_PRIMES[] = {
3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997,
};
#define N_SMALL_PRIMES (sizeof(SMALL_PRIMES)/sizeof(bdigit_t))
int generateRSAPrime(BIGD p, size_t nbits, bdigit_t e, size_t ntests,
const unsigned char *seed, size_t seedlen, BD_RANDFUNC randFunc)
/* Create a prime p such that gcd(p-1, e) = 1.
Returns # prime tests carried out or -1 if failed.
Sets the TWO highest bits to ensure that the
product pq will always have its high bit set.
e MUST be a prime > 2.
This function assumes that e is prime so we can
do the less expensive test p mod e != 1 instead
of gcd(p-1, e) == 1.
Uses improvement in trial division from Menezes 4.51.
*/
{
BIGD u;
size_t i, j, iloop, maxloops, maxodd;
int done, overflow, failedtrial;
int count = 0;
bdigit_t r[N_SMALL_PRIMES];
/* Create a temp */
u = bdNew();
maxodd = nbits * 100;
maxloops = 5;
done = 0;
for (iloop = 0; !done && iloop < maxloops; iloop++)
{
/* Set candidate n0 as random odd number */
bdRandomSeeded(p, nbits, seed, seedlen, randFunc);
/* Set two highest and low bits */
bdSetBit(p, nbits - 1, 1);
bdSetBit(p, nbits - 2, 1);
bdSetBit(p, 0, 1);
/* To improve trial division, compute table R[q] = n0 mod q
for each odd prime q <= B
*/
for (i = 0; i < N_SMALL_PRIMES; i++)
{
r[i] = bdShortMod(u, p, SMALL_PRIMES[i]);
}
done = overflow = 0;
/* Try every odd number n0, n0+2, n0+4,... until we succeed */
for (j = 0; j < maxodd; j++, overflow = bdShortAdd(p, p, 2))
{
/* Check for overflow */
if (overflow)
break;
give_a_sign('.');
count++;
/* Each time 2 is added to the current candidate
update table R[q] = (R[q] + 2) mod q */
if (j > 0)
{
for (i = 0; i < N_SMALL_PRIMES; i++)
{
r[i] = (r[i] + 2) % SMALL_PRIMES[i];
}
}
/* Candidate passes the trial division stage if and only if
NONE of the R[q] values equal zero */
for (failedtrial = 0, i = 0; i < N_SMALL_PRIMES; i++)
{
if (r[i] == 0)
{
failedtrial = 1;
break;
}
}
if (failedtrial)
continue;
/* If p mod e = 1 then gcd(p, e) > 1, so try again */
bdShortMod(u, p, e);
if (bdShortCmp(u, 1) == 0)
continue;
/* Do expensive primality test */
give_a_sign('*');
if (bdRabinMiller(p, ntests))
{ /* Success! - we have a prime */
done = 1;
break;
}
}
}
/* Clear up */
bdFree(&u);
printf("\n");
return (done ? count : -1);
}
int generateRSAKey(BIGD n, BIGD e, BIGD d, BIGD p, BIGD q, BIGD dP, BIGD dQ, BIGD qInv,
size_t nbits, bdigit_t ee, size_t ntests, unsigned char *seed, size_t seedlen,
BD_RANDFUNC randFunc)
{
BIGD g, p1, q1, phi;
size_t np, nq;
unsigned char *myseed = NULL;
clock_t start, finish;
double duration, tmake;
long ptests;
int res;
/* Initialise */
g = bdNew();
p1 = bdNew();
q1 = bdNew();
phi = bdNew();
printf("Generating a %d-bit RSA key...\n", nbits);
/* We add an extra byte to the user-supplied seed */
myseed = malloc(seedlen + 1);
if (!myseed) return -1;
memcpy(myseed, seed, seedlen);
/* Do (p, q) in two halves, approx equal */
nq = nbits / 2 ;
np = nbits - nq;
/* Make sure seeds are slightly different for p and q */
myseed[seedlen] = 0x01;
start = clock();
res = generateRSAPrime(p, np, ee, ntests, myseed, seedlen+1, randFunc);
finish = clock();
bdPrintHex("p=", p, "\n");
assert(res > 0);
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("generateRSAPrime took %.3f secs and %d prime candidates (%.4f s/test)\n", duration, res, duration / res);
ptests = res;
tmake = duration;
printf("p is %d bits\n", bdBitLength(p));
myseed[seedlen] = 0xff;
start = clock();
res = generateRSAPrime(q, nq, ee, ntests, myseed, seedlen+1, randFunc);
finish = clock();
bdPrintHex("q=", q, "\n");
assert(res > 0);
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("generateRSAPrime took %.3f secs and %d prime candidates (%.4f s/test)\n", duration, res, duration / res);
ptests += res;
tmake += duration;
printf("q is %d bits\n", bdBitLength(q));
/* Check that p != q (if so, RNG is faulty!) */
assert(!bdIsEqual(p, q));
bdSetShort(e, ee);
bdPrintHex("e=", e, "\n");
/* If q > p swap p and q so p > q */
if (bdCompare(p, q) < 1)
{
bdSetEqual(g, p);
bdSetEqual(p, q);
bdSetEqual(q, g);
}
/* Calc p-1 and q-1 */
bdSetEqual(p1, p);
bdDecrement(p1);
bdPrintHex("p-1=\n", p1, "\n");
bdSetEqual(q1, q);
bdDecrement(q1);
bdPrintHex("q-1=\n", q1, "\n");
/* Check gcd(p-1, e) = 1 */
bdGcd(g, p1, e);
bdPrintHex("gcd(p-1,e)=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
bdGcd(g, q1, e);
bdPrintHex("gcd(q-1,e)=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
/* Compute n = pq */
bdMultiply(n, p, q);
bdPrintHex("n=\n", n, "\n");
/* Compute d = e^-1 mod (p-1)(q-1) */
bdMultiply(phi, p1, q1);
bdPrintHex("phi=\n", phi, "\n");
res = bdModInv(d, e, phi);
assert(res == 0);
bdPrintHex("d=\n", d, "\n");
/* Check ed = 1 mod phi */
bdModMult(g, e, d, phi);
bdPrintHex("ed mod phi=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
/* Calculate CRT key values */
printf("CRT values:\n");
bdModInv(dP, e, p1);
bdModInv(dQ, e, q1);
bdModInv(qInv, q, p);
bdPrintHex("dP=", dP, "\n");
bdPrintHex("dQ=", dQ, "\n");
bdPrintHex("qInv=", qInv, "\n");
printf("\nTime to create key = %.3f secs with %ld prime candidates (%.4f s/test)\n\n", tmake, ptests, tmake / ptests);
printf("n is %d bits\n", bdBitLength(n));
/* Clean up */
if (myseed) free(myseed);
bdFree(&g);
bdFree(&p1);
bdFree(&q1);
bdFree(&phi);
return 0;
}
static int debug = 0;
int main(void)
{
size_t nbits = 1025; /* (use an odd modulus size to see if it breaks anything!) */
unsigned ee = 0x3;
size_t ntests = 50;
unsigned char *seed = NULL;
size_t seedlen = 0;
BIGD n, e, d, p, q, dP, dQ, qInv;
BIGD m, c, s, hq, h, m1, m2;
int res;
clock_t start, finish;
double tinv, tcrt;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
printf("Test BIGDIGITS with a new %d-bit RSA key and random data.\n", nbits);
/* Initialise */
p = bdNew();
q = bdNew();
n = bdNew();
e = bdNew();
d = bdNew();
dP= bdNew();
dQ= bdNew();
qInv= bdNew();
m = bdNew();
c = bdNew();
s = bdNew();
m1 = bdNew();
m2 = bdNew();
h = bdNew();
hq = bdNew();
/* Create RSA key pair (n, e),(d, p, q, dP, dQ, qInv) */
/* NB we use simple my_rand() here -- you should use a proper cryptographically-secure RNG */
res = generateRSAKey(n, e, d, p, q, dP, dQ, qInv, nbits, ee, ntests, seed, seedlen, my_rand);
if (res != 0)
{
printf("Failed to generate RSA key!\n");
goto clean_up;
}
/* Set a random message m < n */
bdRandomSeeded(m, bdBitLength(n)-1, NULL, 0, my_rand);
bdPrintHex("m=\n", m, "\n");
/* Encrypt c = m^e mod n */
bdModExp(c, m, e, n);
bdPrintHex("c=\n", c, "\n");
/* Check decrypt m1 = c^d mod n */
start = clock();
bdModExp(m1, c, d, n);
finish = clock();
tinv = (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("Decryption %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
printf("Decrypt by inversion took %.3f secs\n", tinv);
/* Sign s = m^d mod n */
bdModExp(s, m, d, n);
bdPrintHex("s=\n", s, "\n");
/* Check verify m1 = s^e mod n */
bdModExp(m1, s, e, n);
bdPrintHex("m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("Verification %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
/* Decrypt using CRT method - Ref: PKCS #1 */
bdPrintHex("m=", m, "\n");
bdPrintHex("c=", c, "\n");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
start = clock();
/* Let m_1 = c^dP mod p. */
bdModExp(m1, c, dP, p);
if(debug)bdPrintHex("m_1=c^dP mod p=", m1, "\n");
/* Let m_2 = c^dQ mod q. */
bdModExp(m2, c, dQ, q);
if(debug)bdPrintHex("m_2=c^dQ mod q=", m2, "\n");
if (bdCompare(m1, m2) < 0)
bdAdd(m1, m1, p);
bdSubtract(m1, m1, m2);
if(debug)bdPrintHex("m_1 - m_2=", m1, "\n");
/* Let h = qInv ( m_1 - m_2 ) mod p. */
bdModMult(h, qInv, m1, p);
if(debug)bdPrintHex("h=qInv(m1-m2) mod p=", h, "\n");
bdMultiply(hq, h, q);
if(debug)bdPrintHex("hq=", hq, "\n");
/* Let m = m_2 + hq. */
bdAdd(m1, m2, hq);
finish = clock();
tcrt = (double)(finish - start) / CLOCKS_PER_SEC;
if(debug)bdPrintHex("m'=m_2 + hq=", m1, "\n");
bdPrintHex("(CRT)m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("CRT Decryption %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
printf("Decrypt by CRT took %.3f secs\n", tcrt);
printf("c.f. Decrypt by inversion %.3f secs (factor = %.1f)\n",
tinv, (tcrt ? tinv / tcrt : 0));
printf("n is %d bits\n", bdBitLength(n));
/* Clean up */
clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
bdFree(&dP);
bdFree(&dQ);
bdFree(&qInv);
bdFree(&m);
bdFree(&c);
bdFree(&s);
bdFree(&m1);
bdFree(&m2);
bdFree(&h);
bdFree(&hq);
printf("OK, successfully completed tests.\n");
return 0;
}
/* $Id: t_bdRSA.c $ */
/* Test BigDigits "bd" functions using a new RSA key and random data */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "bigd.h"
static int my_rand(unsigned char *bytes, size_t nbytes, const unsigned char *seed, size_t seedlen)
/* Our own (very insecure) random generator func using good old rand()
but in the required format for BD_RANDFUNC
-- replace this in practice with your own cryptographically-secure function
-- or use bdRandomOctets() in bigdRand.h
*/
{
unsigned int myseed;
size_t i;
int offset;
/* Use time for 32-bit seed - then blend in user-supplied seed, if any */
myseed = (unsigned)time(NULL) ^ (unsigned)clock();
if (seed)
{
for (offset = 0, i = 0; i < seedlen; i++, offset = (offset + 1) % sizeof(unsigned))
myseed ^= ((unsigned int)seed[i] << (offset * 8));
}
srand(myseed);
while (nbytes--)
{
*bytes++ = rand() & 0xFF;
}
return 0;
}
#define give_a_sign(c) putchar((c))
static bdigit_t SMALL_PRIMES[] = {
3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997,
};
#define N_SMALL_PRIMES (sizeof(SMALL_PRIMES)/sizeof(bdigit_t))
int generateRSAPrime(BIGD p, size_t nbits, bdigit_t e, size_t ntests,
const unsigned char *seed, size_t seedlen, BD_RANDFUNC randFunc)
/* Create a prime p such that gcd(p-1, e) = 1.
Returns # prime tests carried out or -1 if failed.
Sets the TWO highest bits to ensure that the
product pq will always have its high bit set.
e MUST be a prime > 2.
This function assumes that e is prime so we can
do the less expensive test p mod e != 1 instead
of gcd(p-1, e) == 1.
Uses improvement in trial division from Menezes 4.51.
*/
{
BIGD u;
size_t i, j, iloop, maxloops, maxodd;
int done, overflow, failedtrial;
int count = 0;
bdigit_t r[N_SMALL_PRIMES];
/* Create a temp */
u = bdNew();
maxodd = nbits * 100;
maxloops = 5;
done = 0;
for (iloop = 0; !done && iloop < maxloops; iloop++)
{
/* Set candidate n0 as random odd number */
bdRandomSeeded(p, nbits, seed, seedlen, randFunc);
/* Set two highest and low bits */
bdSetBit(p, nbits - 1, 1);
bdSetBit(p, nbits - 2, 1);
bdSetBit(p, 0, 1);
/* To improve trial division, compute table R[q] = n0 mod q
for each odd prime q <= B
*/
for (i = 0; i < N_SMALL_PRIMES; i++)
{
r[i] = bdShortMod(u, p, SMALL_PRIMES[i]);
}
done = overflow = 0;
/* Try every odd number n0, n0+2, n0+4,... until we succeed */
for (j = 0; j < maxodd; j++, overflow = bdShortAdd(p, p, 2))
{
/* Check for overflow */
if (overflow)
break;
give_a_sign('.');
count++;
/* Each time 2 is added to the current candidate
update table R[q] = (R[q] + 2) mod q */
if (j > 0)
{
for (i = 0; i < N_SMALL_PRIMES; i++)
{
r[i] = (r[i] + 2) % SMALL_PRIMES[i];
}
}
/* Candidate passes the trial division stage if and only if
NONE of the R[q] values equal zero */
for (failedtrial = 0, i = 0; i < N_SMALL_PRIMES; i++)
{
if (r[i] == 0)
{
failedtrial = 1;
break;
}
}
if (failedtrial)
continue;
/* If p mod e = 1 then gcd(p, e) > 1, so try again */
bdShortMod(u, p, e);
if (bdShortCmp(u, 1) == 0)
continue;
/* Do expensive primality test */
give_a_sign('*');
if (bdRabinMiller(p, ntests))
{ /* Success! - we have a prime */
done = 1;
break;
}
}
}
/* Clear up */
bdFree(&u);
printf("\n");
return (done ? count : -1);
}
int generateRSAKey(BIGD n, BIGD e, BIGD d, BIGD p, BIGD q, BIGD dP, BIGD dQ, BIGD qInv,
size_t nbits, bdigit_t ee, size_t ntests, unsigned char *seed, size_t seedlen,
BD_RANDFUNC randFunc)
{
BIGD g, p1, q1, phi;
size_t np, nq;
unsigned char *myseed = NULL;
clock_t start, finish;
double duration, tmake;
long ptests;
int res;
/* Initialise */
g = bdNew();
p1 = bdNew();
q1 = bdNew();
phi = bdNew();
printf("Generating a %d-bit RSA key...\n", nbits);
/* We add an extra byte to the user-supplied seed */
myseed = malloc(seedlen + 1);
if (!myseed) return -1;
memcpy(myseed, seed, seedlen);
/* Do (p, q) in two halves, approx equal */
nq = nbits / 2 ;
np = nbits - nq;
/* Make sure seeds are slightly different for p and q */
myseed[seedlen] = 0x01;
start = clock();
res = generateRSAPrime(p, np, ee, ntests, myseed, seedlen+1, randFunc);
finish = clock();
bdPrintHex("p=", p, "\n");
assert(res > 0);
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("generateRSAPrime took %.3f secs and %d prime candidates (%.4f s/test)\n", duration, res, duration / res);
ptests = res;
tmake = duration;
printf("p is %d bits\n", bdBitLength(p));
myseed[seedlen] = 0xff;
start = clock();
res = generateRSAPrime(q, nq, ee, ntests, myseed, seedlen+1, randFunc);
finish = clock();
bdPrintHex("q=", q, "\n");
assert(res > 0);
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("generateRSAPrime took %.3f secs and %d prime candidates (%.4f s/test)\n", duration, res, duration / res);
ptests += res;
tmake += duration;
printf("q is %d bits\n", bdBitLength(q));
/* Check that p != q (if so, RNG is faulty!) */
assert(!bdIsEqual(p, q));
bdSetShort(e, ee);
bdPrintHex("e=", e, "\n");
/* If q > p swap p and q so p > q */
if (bdCompare(p, q) < 1)
{
bdSetEqual(g, p);
bdSetEqual(p, q);
bdSetEqual(q, g);
}
/* Calc p-1 and q-1 */
bdSetEqual(p1, p);
bdDecrement(p1);
bdPrintHex("p-1=\n", p1, "\n");
bdSetEqual(q1, q);
bdDecrement(q1);
bdPrintHex("q-1=\n", q1, "\n");
/* Check gcd(p-1, e) = 1 */
bdGcd(g, p1, e);
bdPrintHex("gcd(p-1,e)=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
bdGcd(g, q1, e);
bdPrintHex("gcd(q-1,e)=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
/* Compute n = pq */
bdMultiply(n, p, q);
bdPrintHex("n=\n", n, "\n");
/* Compute d = e^-1 mod (p-1)(q-1) */
bdMultiply(phi, p1, q1);
bdPrintHex("phi=\n", phi, "\n");
res = bdModInv(d, e, phi);
assert(res == 0);
bdPrintHex("d=\n", d, "\n");
/* Check ed = 1 mod phi */
bdModMult(g, e, d, phi);
bdPrintHex("ed mod phi=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
/* Calculate CRT key values */
printf("CRT values:\n");
bdModInv(dP, e, p1);
bdModInv(dQ, e, q1);
bdModInv(qInv, q, p);
bdPrintHex("dP=", dP, "\n");
bdPrintHex("dQ=", dQ, "\n");
bdPrintHex("qInv=", qInv, "\n");
printf("\nTime to create key = %.3f secs with %ld prime candidates (%.4f s/test)\n\n", tmake, ptests, tmake / ptests);
printf("n is %d bits\n", bdBitLength(n));
/* Clean up */
if (myseed) free(myseed);
bdFree(&g);
bdFree(&p1);
bdFree(&q1);
bdFree(&phi);
return 0;
}
static int debug = 0;
int main(void)
{
size_t nbits = 1025; /* (use an odd modulus size to see if it breaks anything!) */
unsigned ee = 0x3;
size_t ntests = 50;
unsigned char *seed = NULL;
size_t seedlen = 0;
BIGD n, e, d, p, q, dP, dQ, qInv;
BIGD m, c, s, hq, h, m1, m2;
int res;
clock_t start, finish;
double tinv, tcrt;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
printf("Test BIGDIGITS with a new %d-bit RSA key and random data.\n", nbits);
/* Initialise */
p = bdNew();
q = bdNew();
n = bdNew();
e = bdNew();
d = bdNew();
dP= bdNew();
dQ= bdNew();
qInv= bdNew();
m = bdNew();
c = bdNew();
s = bdNew();
m1 = bdNew();
m2 = bdNew();
h = bdNew();
hq = bdNew();
/* Create RSA key pair (n, e),(d, p, q, dP, dQ, qInv) */
/* NB we use simple my_rand() here -- you should use a proper cryptographically-secure RNG */
res = generateRSAKey(n, e, d, p, q, dP, dQ, qInv, nbits, ee, ntests, seed, seedlen, my_rand);
if (res != 0)
{
printf("Failed to generate RSA key!\n");
goto clean_up;
}
/* Set a random message m < n */
bdRandomSeeded(m, bdBitLength(n)-1, NULL, 0, my_rand);
bdPrintHex("m=\n", m, "\n");
/* Encrypt c = m^e mod n */
bdModExp(c, m, e, n);
bdPrintHex("c=\n", c, "\n");
/* Check decrypt m1 = c^d mod n */
start = clock();
bdModExp(m1, c, d, n);
finish = clock();
tinv = (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("Decryption %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
printf("Decrypt by inversion took %.3f secs\n", tinv);
/* Sign s = m^d mod n */
bdModExp(s, m, d, n);
bdPrintHex("s=\n", s, "\n");
/* Check verify m1 = s^e mod n */
bdModExp(m1, s, e, n);
bdPrintHex("m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("Verification %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
/* Decrypt using CRT method - Ref: PKCS #1 */
bdPrintHex("m=", m, "\n");
bdPrintHex("c=", c, "\n");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
start = clock();
/* Let m_1 = c^dP mod p. */
bdModExp(m1, c, dP, p);
if(debug)bdPrintHex("m_1=c^dP mod p=", m1, "\n");
/* Let m_2 = c^dQ mod q. */
bdModExp(m2, c, dQ, q);
if(debug)bdPrintHex("m_2=c^dQ mod q=", m2, "\n");
if (bdCompare(m1, m2) < 0)
bdAdd(m1, m1, p);
bdSubtract(m1, m1, m2);
if(debug)bdPrintHex("m_1 - m_2=", m1, "\n");
/* Let h = qInv ( m_1 - m_2 ) mod p. */
bdModMult(h, qInv, m1, p);
if(debug)bdPrintHex("h=qInv(m1-m2) mod p=", h, "\n");
bdMultiply(hq, h, q);
if(debug)bdPrintHex("hq=", hq, "\n");
/* Let m = m_2 + hq. */
bdAdd(m1, m2, hq);
finish = clock();
tcrt = (double)(finish - start) / CLOCKS_PER_SEC;
if(debug)bdPrintHex("m'=m_2 + hq=", m1, "\n");
bdPrintHex("(CRT)m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("CRT Decryption %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
printf("Decrypt by CRT took %.3f secs\n", tcrt);
printf("c.f. Decrypt by inversion %.3f secs (factor = %.1f)\n",
tinv, (tcrt ? tinv / tcrt : 0));
printf("n is %d bits\n", bdBitLength(n));
/* Clean up */
clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
bdFree(&dP);
bdFree(&dQ);
bdFree(&qInv);
bdFree(&m);
bdFree(&c);
bdFree(&s);
bdFree(&m1);
bdFree(&m2);
bdFree(&h);
bdFree(&hq);
printf("OK, successfully completed tests.\n");
return 0;
}

View File

@ -1,402 +1,402 @@
/* $Id: t_bdRSA1.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* Test BigDigits "bd" functions using a new RSA key and user input plaintext
NOTE: this uses a different algorithm to generate the random number (a better one,
still not quite cryptographically secure, but much better than using rand()).
It also uses a more convenient key length of 1024 which is an exact multiple of 8.
The "message" to be encrypted is accepted from the command-line or defaults to "abc".
The message length is restricted to 117 bytes by the size of the key (|n|-11).
*/
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "bigd.h"
#include "bigdRand.h"
static void pr_bytesmsg(char *msg, unsigned char *bytes, size_t len)
{
size_t i;
printf("%s", msg);
for (i = 0; i < len; i++)
printf("%02x", bytes[i]);
printf("\n");
}
int generateRSAKey(BIGD n, BIGD e, BIGD d, BIGD p, BIGD q, BIGD dP, BIGD dQ, BIGD qInv,
size_t nbits, bdigit_t ee, size_t ntests, unsigned char *seed, size_t seedlen,
BD_RANDFUNC randFunc)
{
BIGD g, p1, q1, phi;
size_t np, nq;
unsigned char *myseed = NULL;
clock_t start, finish;
double duration, tmake;
int res;
/* Initialise */
g = bdNew();
p1 = bdNew();
q1 = bdNew();
phi = bdNew();
printf("Generating a %d-bit RSA key...\n", nbits);
/* Set e as a BigDigit from short value ee */
bdSetShort(e, ee);
bdPrintHex("e=", e, "\n");
/* We add an extra byte to the user-supplied seed */
myseed = malloc(seedlen + 1);
if (!myseed) return -1;
memcpy(myseed, seed, seedlen);
/* Make sure seeds are slightly different for p and q */
myseed[seedlen] = 0x01;
/* Do (p, q) in two halves, approx equal */
nq = nbits / 2 ;
np = nbits - nq;
/* Compute two primes of required length with p mod e > 1 and *second* highest bit set */
start = clock();
do {
bdGeneratePrime(p, np, ntests, myseed, seedlen+1, randFunc);
bdPrintHex("Try p=", p, "\n");
} while ((bdShortMod(g, p, ee) == 1) || bdGetBit(p, np-2) == 0);
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
tmake = duration;
printf("p is %d bits, bit(%d) is %d\n", bdBitLength(p), np-2, bdGetBit(p,np-2));
myseed[seedlen] = 0xff;
start = clock();
do {
bdGeneratePrime(q, nq, ntests, myseed, seedlen+1, randFunc);
bdPrintHex("Try q=", q, "\n");
} while ((bdShortMod(g, q, ee) == 1) || bdGetBit(q, nq-2) == 0);
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
tmake += duration;
printf("q is %d bits, bit(%d) is %d\n", bdBitLength(q), nq-2, bdGetBit(q,nq-2));
printf("Prime generation took %.3f secs\n", duration);
/* Compute n = pq */
bdMultiply(n, p, q);
bdPrintHex("n=\n", n, "\n");
printf("n is %d bits\n", bdBitLength(n));
assert(bdBitLength(n) == nbits);
/* Check that p != q (if so, RNG is faulty!) */
assert(!bdIsEqual(p, q));
/* If q > p swap p and q so p > q */
if (bdCompare(p, q) < 1)
{
printf("Swopping p and q so p > q...\n");
bdSetEqual(g, p);
bdSetEqual(p, q);
bdSetEqual(q, g);
}
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
/* Calc p-1 and q-1 */
bdSetEqual(p1, p);
bdDecrement(p1);
bdPrintHex("p-1=\n", p1, "\n");
bdSetEqual(q1, q);
bdDecrement(q1);
bdPrintHex("q-1=\n", q1, "\n");
/* Compute phi = (p-1)(q-1) */
bdMultiply(phi, p1, q1);
bdPrintHex("phi=\n", phi, "\n");
/* Check gcd(phi, e) == 1 */
bdGcd(g, phi, e);
bdPrintHex("gcd(phi,e)=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
/* Compute inverse of e modulo phi: d = 1/e mod (p-1)(q-1) */
res = bdModInv(d, e, phi);
assert(res == 0);
bdPrintHex("d=\n", d, "\n");
/* Check ed = 1 mod phi */
bdModMult(g, e, d, phi);
bdPrintHex("ed mod phi=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
/* Calculate CRT key values */
printf("CRT values:\n");
bdModInv(dP, e, p1);
bdModInv(dQ, e, q1);
bdModInv(qInv, q, p);
bdPrintHex("dP=", dP, "\n");
bdPrintHex("dQ=", dQ, "\n");
bdPrintHex("qInv=", qInv, "\n");
printf("n is %d bits\n", bdBitLength(n));
/* Clean up */
if (myseed) free(myseed);
bdFree(&g);
bdFree(&p1);
bdFree(&q1);
bdFree(&phi);
return 0;
}
#define KEYSIZE 1024
static int debug = 0;
int main(int argc, char *argv[])
{
size_t nbits = KEYSIZE; /* NB a multiple of 8 here */
int klen, mlen;
int npad, i;
unsigned char rb;
unsigned char block[(KEYSIZE+7)/8];
unsigned ee = 0x3;
size_t ntests = 50;
unsigned char *seed = NULL;
size_t seedlen = 0;
char msgstr[sizeof(block)];
int nchars;
unsigned char *pmsg = "abc"; /* Default message */
BIGD n, e, d, p, q, dP, dQ, qInv;
BIGD m, c, s, hq, h, m1, m2;
int res;
clock_t start, finish;
double tinv, tcrt;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
if (argc > 1)
{ /* Use message supplied in command line */
pmsg = (unsigned char*)argv[1];
}
printf("Test BIGDIGITS with a new %d-bit RSA key and given message data.\n", nbits);
/* Initialise */
p = bdNew();
q = bdNew();
n = bdNew();
e = bdNew();
d = bdNew();
dP= bdNew();
dQ= bdNew();
qInv= bdNew();
m = bdNew();
c = bdNew();
s = bdNew();
m1 = bdNew();
m2 = bdNew();
h = bdNew();
hq = bdNew();
/* Create RSA key pair (n, e),(d, p, q, dP, dQ, qInv) */
/* NB you should use a proper cryptographically-secure RNG */
res = generateRSAKey(n, e, d, p, q, dP, dQ, qInv, nbits, ee, ntests, seed, seedlen, bdRandomOctets);
if (res != 0)
{
printf("Failed to generate RSA key!\n");
goto clean_up;
}
/* Create a PKCS#1 v1.5 EME message block in octet format */
/*
|<-----------------(klen bytes)--------------->|
+--+--+-------+--+-----------------------------+
|00|02|PADDING|00| DATA TO ENCRYPT |
+--+--+-------+--+-----------------------------+
The padding is made up of _at least_ eight non-zero random bytes.
*/
/* How big is the key in octets (8-bit bytes)? */
klen = (nbits + 7) / 8;
/* CAUTION: make sure the block is at least klen bytes long */
memset(block, 0, klen);
mlen = strlen(pmsg);
npad = klen - mlen - 3;
if (npad < 8) /* Note npad is a signed int, not a size_t */
{
printf("Message is too long\n");
exit(1);
}
/* Display */
printf("Message='%s' ", pmsg);
pr_bytesmsg("0x", pmsg, strlen((char*)pmsg));
/* Create encryption block */
block[0] = 0x00;
block[1] = 0x02;
/* Generate npad non-zero padding bytes - rand() is OK */
srand((unsigned)time(NULL));
for (i = 0; i < npad; i++)
{
while ((rb = (rand() & 0xFF)) == 0)
;/* loop until non-zero*/
block[i+2] = rb;
}
block[npad+2] = 0x00;
memcpy(&block[npad+3], pmsg, mlen);
/* Convert to BIGD format */
bdConvFromOctets(m, block, klen);
bdPrintHex("m=\n", m, "\n");
/* Encrypt c = m^e mod n */
bdModExp(c, m, e, n);
bdPrintHex("c=\n", c, "\n");
/* Check decrypt m1 = c^d mod n */
start = clock();
bdModExp(m1, c, d, n);
finish = clock();
tinv = (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("Decryption %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
printf("Decrypt by inversion took %.3f secs\n", tinv);
/* Extract the message bytes from the decrypted block */
memset(block, 0, klen);
bdConvToOctets(m, block, klen);
assert(block[0] == 0x00);
assert(block[1] == 0x02);
for (i = 2; i < klen; i++)
{ /* Look for zero separating byte */
if (block[i] == 0x00)
break;
}
if (i >= klen)
printf("ERROR: failed to find message in decrypted block\n");
else
{
nchars = klen - i - 1;
memcpy(msgstr, &block[i+1], nchars);
msgstr[nchars] = '\0';
printf("Decrypted message is '%s'\n", msgstr);
}
/* Sign s = m^d mod n (NB m is not a valid PKCS-v1_5 signature block) */
bdModExp(s, m, d, n);
bdPrintHex("s=\n", s, "\n");
/* Continue as original t_bdRSA ... */
/* Check verify m1 = s^e mod n */
bdModExp(m1, s, e, n);
bdPrintHex("m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("Verification %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
/* Decrypt using CRT method - Ref: PKCS #1 */
bdPrintHex("m=", m, "\n");
bdPrintHex("c=", c, "\n");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
start = clock();
/* Let m_1 = c^dP mod p. */
bdModExp(m1, c, dP, p);
if(debug)bdPrintHex("m_1=c^dP mod p=", m1, "\n");
/* Let m_2 = c^dQ mod q. */
bdModExp(m2, c, dQ, q);
if(debug)bdPrintHex("m_2=c^dQ mod q=", m2, "\n");
if (bdCompare(m1, m2) < 0)
bdAdd(m1, m1, p);
bdSubtract(m1, m1, m2);
if(debug)bdPrintHex("m_1 - m_2=", m1, "\n");
/* Let h = qInv ( m_1 - m_2 ) mod p. */
bdModMult(h, qInv, m1, p);
if(debug)bdPrintHex("h=qInv(m1-m2) mod p=", h, "\n");
bdMultiply(hq, h, q);
if(debug)bdPrintHex("hq=", hq, "\n");
/* Let m = m_2 + hq. */
bdAdd(m1, m2, hq);
finish = clock();
tcrt = (double)(finish - start) / CLOCKS_PER_SEC;
if(debug)bdPrintHex("m'=m_2 + hq=", m1, "\n");
bdPrintHex("(CRT)m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("CRT Decryption %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
printf("Decrypt by CRT took %.3f secs\n", tcrt);
printf("c.f. Decrypt by inversion %.3f secs (factor = %.1f)\n",
tinv, (tcrt ? tinv / tcrt : 0));
printf("n is %d bits\n", bdBitLength(n));
/* Clean up */
clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
bdFree(&dP);
bdFree(&dQ);
bdFree(&qInv);
bdFree(&m);
bdFree(&c);
bdFree(&s);
bdFree(&m1);
bdFree(&m2);
bdFree(&h);
bdFree(&hq);
/* Show the current version number */
printf("Version=%d\n", bdVersion());
printf("OK, successfully completed tests.\n");
return 0;
}
/* $Id: t_bdRSA1.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* Test BigDigits "bd" functions using a new RSA key and user input plaintext
NOTE: this uses a different algorithm to generate the random number (a better one,
still not quite cryptographically secure, but much better than using rand()).
It also uses a more convenient key length of 1024 which is an exact multiple of 8.
The "message" to be encrypted is accepted from the command-line or defaults to "abc".
The message length is restricted to 117 bytes by the size of the key (|n|-11).
*/
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "bigd.h"
#include "bigdRand.h"
static void pr_bytesmsg(char *msg, unsigned char *bytes, size_t len)
{
size_t i;
printf("%s", msg);
for (i = 0; i < len; i++)
printf("%02x", bytes[i]);
printf("\n");
}
int generateRSAKey(BIGD n, BIGD e, BIGD d, BIGD p, BIGD q, BIGD dP, BIGD dQ, BIGD qInv,
size_t nbits, bdigit_t ee, size_t ntests, unsigned char *seed, size_t seedlen,
BD_RANDFUNC randFunc)
{
BIGD g, p1, q1, phi;
size_t np, nq;
unsigned char *myseed = NULL;
clock_t start, finish;
double duration, tmake;
int res;
/* Initialise */
g = bdNew();
p1 = bdNew();
q1 = bdNew();
phi = bdNew();
printf("Generating a %d-bit RSA key...\n", nbits);
/* Set e as a BigDigit from short value ee */
bdSetShort(e, ee);
bdPrintHex("e=", e, "\n");
/* We add an extra byte to the user-supplied seed */
myseed = malloc(seedlen + 1);
if (!myseed) return -1;
memcpy(myseed, seed, seedlen);
/* Make sure seeds are slightly different for p and q */
myseed[seedlen] = 0x01;
/* Do (p, q) in two halves, approx equal */
nq = nbits / 2 ;
np = nbits - nq;
/* Compute two primes of required length with p mod e > 1 and *second* highest bit set */
start = clock();
do {
bdGeneratePrime(p, np, ntests, myseed, seedlen+1, randFunc);
bdPrintHex("Try p=", p, "\n");
} while ((bdShortMod(g, p, ee) == 1) || bdGetBit(p, np-2) == 0);
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
tmake = duration;
printf("p is %d bits, bit(%d) is %d\n", bdBitLength(p), np-2, bdGetBit(p,np-2));
myseed[seedlen] = 0xff;
start = clock();
do {
bdGeneratePrime(q, nq, ntests, myseed, seedlen+1, randFunc);
bdPrintHex("Try q=", q, "\n");
} while ((bdShortMod(g, q, ee) == 1) || bdGetBit(q, nq-2) == 0);
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
tmake += duration;
printf("q is %d bits, bit(%d) is %d\n", bdBitLength(q), nq-2, bdGetBit(q,nq-2));
printf("Prime generation took %.3f secs\n", duration);
/* Compute n = pq */
bdMultiply(n, p, q);
bdPrintHex("n=\n", n, "\n");
printf("n is %d bits\n", bdBitLength(n));
assert(bdBitLength(n) == nbits);
/* Check that p != q (if so, RNG is faulty!) */
assert(!bdIsEqual(p, q));
/* If q > p swap p and q so p > q */
if (bdCompare(p, q) < 1)
{
printf("Swopping p and q so p > q...\n");
bdSetEqual(g, p);
bdSetEqual(p, q);
bdSetEqual(q, g);
}
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
/* Calc p-1 and q-1 */
bdSetEqual(p1, p);
bdDecrement(p1);
bdPrintHex("p-1=\n", p1, "\n");
bdSetEqual(q1, q);
bdDecrement(q1);
bdPrintHex("q-1=\n", q1, "\n");
/* Compute phi = (p-1)(q-1) */
bdMultiply(phi, p1, q1);
bdPrintHex("phi=\n", phi, "\n");
/* Check gcd(phi, e) == 1 */
bdGcd(g, phi, e);
bdPrintHex("gcd(phi,e)=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
/* Compute inverse of e modulo phi: d = 1/e mod (p-1)(q-1) */
res = bdModInv(d, e, phi);
assert(res == 0);
bdPrintHex("d=\n", d, "\n");
/* Check ed = 1 mod phi */
bdModMult(g, e, d, phi);
bdPrintHex("ed mod phi=", g, "\n");
assert(bdShortCmp(g, 1) == 0);
/* Calculate CRT key values */
printf("CRT values:\n");
bdModInv(dP, e, p1);
bdModInv(dQ, e, q1);
bdModInv(qInv, q, p);
bdPrintHex("dP=", dP, "\n");
bdPrintHex("dQ=", dQ, "\n");
bdPrintHex("qInv=", qInv, "\n");
printf("n is %d bits\n", bdBitLength(n));
/* Clean up */
if (myseed) free(myseed);
bdFree(&g);
bdFree(&p1);
bdFree(&q1);
bdFree(&phi);
return 0;
}
#define KEYSIZE 1024
static int debug = 0;
int main(int argc, char *argv[])
{
size_t nbits = KEYSIZE; /* NB a multiple of 8 here */
int klen, mlen;
int npad, i;
unsigned char rb;
unsigned char block[(KEYSIZE+7)/8];
unsigned ee = 0x3;
size_t ntests = 50;
unsigned char *seed = NULL;
size_t seedlen = 0;
char msgstr[sizeof(block)];
int nchars;
unsigned char *pmsg = "abc"; /* Default message */
BIGD n, e, d, p, q, dP, dQ, qInv;
BIGD m, c, s, hq, h, m1, m2;
int res;
clock_t start, finish;
double tinv, tcrt;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
if (argc > 1)
{ /* Use message supplied in command line */
pmsg = (unsigned char*)argv[1];
}
printf("Test BIGDIGITS with a new %d-bit RSA key and given message data.\n", nbits);
/* Initialise */
p = bdNew();
q = bdNew();
n = bdNew();
e = bdNew();
d = bdNew();
dP= bdNew();
dQ= bdNew();
qInv= bdNew();
m = bdNew();
c = bdNew();
s = bdNew();
m1 = bdNew();
m2 = bdNew();
h = bdNew();
hq = bdNew();
/* Create RSA key pair (n, e),(d, p, q, dP, dQ, qInv) */
/* NB you should use a proper cryptographically-secure RNG */
res = generateRSAKey(n, e, d, p, q, dP, dQ, qInv, nbits, ee, ntests, seed, seedlen, bdRandomOctets);
if (res != 0)
{
printf("Failed to generate RSA key!\n");
goto clean_up;
}
/* Create a PKCS#1 v1.5 EME message block in octet format */
/*
|<-----------------(klen bytes)--------------->|
+--+--+-------+--+-----------------------------+
|00|02|PADDING|00| DATA TO ENCRYPT |
+--+--+-------+--+-----------------------------+
The padding is made up of _at least_ eight non-zero random bytes.
*/
/* How big is the key in octets (8-bit bytes)? */
klen = (nbits + 7) / 8;
/* CAUTION: make sure the block is at least klen bytes long */
memset(block, 0, klen);
mlen = strlen(pmsg);
npad = klen - mlen - 3;
if (npad < 8) /* Note npad is a signed int, not a size_t */
{
printf("Message is too long\n");
exit(1);
}
/* Display */
printf("Message='%s' ", pmsg);
pr_bytesmsg("0x", pmsg, strlen((char*)pmsg));
/* Create encryption block */
block[0] = 0x00;
block[1] = 0x02;
/* Generate npad non-zero padding bytes - rand() is OK */
srand((unsigned)time(NULL));
for (i = 0; i < npad; i++)
{
while ((rb = (rand() & 0xFF)) == 0)
;/* loop until non-zero*/
block[i+2] = rb;
}
block[npad+2] = 0x00;
memcpy(&block[npad+3], pmsg, mlen);
/* Convert to BIGD format */
bdConvFromOctets(m, block, klen);
bdPrintHex("m=\n", m, "\n");
/* Encrypt c = m^e mod n */
bdModExp(c, m, e, n);
bdPrintHex("c=\n", c, "\n");
/* Check decrypt m1 = c^d mod n */
start = clock();
bdModExp(m1, c, d, n);
finish = clock();
tinv = (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("Decryption %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
printf("Decrypt by inversion took %.3f secs\n", tinv);
/* Extract the message bytes from the decrypted block */
memset(block, 0, klen);
bdConvToOctets(m, block, klen);
assert(block[0] == 0x00);
assert(block[1] == 0x02);
for (i = 2; i < klen; i++)
{ /* Look for zero separating byte */
if (block[i] == 0x00)
break;
}
if (i >= klen)
printf("ERROR: failed to find message in decrypted block\n");
else
{
nchars = klen - i - 1;
memcpy(msgstr, &block[i+1], nchars);
msgstr[nchars] = '\0';
printf("Decrypted message is '%s'\n", msgstr);
}
/* Sign s = m^d mod n (NB m is not a valid PKCS-v1_5 signature block) */
bdModExp(s, m, d, n);
bdPrintHex("s=\n", s, "\n");
/* Continue as original t_bdRSA ... */
/* Check verify m1 = s^e mod n */
bdModExp(m1, s, e, n);
bdPrintHex("m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("Verification %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
/* Decrypt using CRT method - Ref: PKCS #1 */
bdPrintHex("m=", m, "\n");
bdPrintHex("c=", c, "\n");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
start = clock();
/* Let m_1 = c^dP mod p. */
bdModExp(m1, c, dP, p);
if(debug)bdPrintHex("m_1=c^dP mod p=", m1, "\n");
/* Let m_2 = c^dQ mod q. */
bdModExp(m2, c, dQ, q);
if(debug)bdPrintHex("m_2=c^dQ mod q=", m2, "\n");
if (bdCompare(m1, m2) < 0)
bdAdd(m1, m1, p);
bdSubtract(m1, m1, m2);
if(debug)bdPrintHex("m_1 - m_2=", m1, "\n");
/* Let h = qInv ( m_1 - m_2 ) mod p. */
bdModMult(h, qInv, m1, p);
if(debug)bdPrintHex("h=qInv(m1-m2) mod p=", h, "\n");
bdMultiply(hq, h, q);
if(debug)bdPrintHex("hq=", hq, "\n");
/* Let m = m_2 + hq. */
bdAdd(m1, m2, hq);
finish = clock();
tcrt = (double)(finish - start) / CLOCKS_PER_SEC;
if(debug)bdPrintHex("m'=m_2 + hq=", m1, "\n");
bdPrintHex("(CRT)m'=\n", m1, "\n");
res = bdCompare(m1, m);
printf("CRT Decryption %s\n", (res == 0 ? "OK" : "FAILED!"));
assert(res == 0);
printf("Decrypt by CRT took %.3f secs\n", tcrt);
printf("c.f. Decrypt by inversion %.3f secs (factor = %.1f)\n",
tinv, (tcrt ? tinv / tcrt : 0));
printf("n is %d bits\n", bdBitLength(n));
/* Clean up */
clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
bdFree(&dP);
bdFree(&dQ);
bdFree(&qInv);
bdFree(&m);
bdFree(&c);
bdFree(&s);
bdFree(&m1);
bdFree(&m2);
bdFree(&h);
bdFree(&hq);
/* Show the current version number */
printf("Version=%d\n", bdVersion());
printf("OK, successfully completed tests.\n");
return 0;
}

View File

@ -1,245 +1,245 @@
/* $Id: t_bdRSA_blinded.c $ */
/* Carry out RSA calculations using constant-time exponentiation and blinding */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include "bigd.h"
#include "bigdRand.h"
int main(void)
{
size_t nbits;
BIGD N, e, d;
BIGD m, c, r, g, R, S, x, z, y;
int isequal;
size_t i;
clock_t start, finish;
double tinv, tinv_ct, tblind;
int b;
const size_t ntimes = 3;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
printf("Carry out RSA calculation using constant-time exponentiation and blinding.\n");
/* Initialise */
bdNewVars(&N, &e, &d, &m, &c, &y, &r, &g, &R, &S, &x, &z);
/* Read in public and private keys as BIGDs */
/*
Source: Alice's 1024-bit RSA key from [RFC4134]:
/* $Id: t_bdRSA_blinded.c $ */
/* Carry out RSA calculations using constant-time exponentiation and blinding */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#if _MSC_VER >= 1100
/* Detect memory leaks in MSVC++ */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include "bigd.h"
#include "bigdRand.h"
int main(void)
{
size_t nbits;
BIGD N, e, d;
BIGD m, c, r, g, R, S, x, z, y;
int isequal;
size_t i;
clock_t start, finish;
double tinv, tinv_ct, tblind;
int b;
const size_t ntimes = 3;
/* MSVC memory leak checking stuff */
#if _MSC_VER >= 1100
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif
printf("Carry out RSA calculation using constant-time exponentiation and blinding.\n");
/* Initialise */
bdNewVars(&N, &e, &d, &m, &c, &y, &r, &g, &R, &S, &x, &z);
/* Read in public and private keys as BIGDs */
/*
Source: Alice's 1024-bit RSA key from [RFC4134]:
Hoffman, P., Ed., "Examples of S/MIME Messages", RFC 4134, July 2005.
*/
bdConvFromHex(N, "E08973398DD8F5F5E88776397F4EB005BB5383DE0FB7ABDC7DC775290D052E6D12DFA68626D4D26FAA5829FC97ECFA82510F3080BEB1509E4644F12CBBD832CFC6686F07D9B060ACBEEE34096A13F5F7050593DF5EBA3556D961FF197FC981E6F86CEA874070EFAC6D2C749F2DFA553AB9997702A648528C4EF357385774575F");
bdConvFromHex(e, "010001");
bdConvFromHex(d, "A403C327477634346CA686B57949014B2E8AD2C862B2C7D748096A8B91F736F275D6E8CD15906027314735644D95CD6763CEB49F56AC2F376E1CEE0EBF282DF439906F34D86E085BD5656AD841F313D72D395EFE33CBFF29E4030B3D05A28FB7F18EA27637B07957D32F2BDE8706227D04665EC91BAF8B1AC3EC9144AB7F21");
printf("Public key:\n");
bdPrintHex("N=", N, "\n");
bdPrintHex("e=", e, "\n");
printf("Private key:\n");
bdPrintHex("d=", d, "\n");
nbits = bdBitLength(N);
printf("Key size = %d bits\n", nbits);
/* Set a random message m < N */
bdQuickRandBits(m, nbits-8);
bdPrintHex("Random plaintext m =\n", m, "\n");
/* Encrypt c = m^e mod N */
/* NB no need to use constant-time modexp when using public exponent */
bdModExp(c, m, e, N);
bdPrintHex("Ciphertext c=m^e mod N=\n", c, "\n");
printf("\nSIMPLE DECRYPTION USING PRIVATE EXPONENT...\n");
/* Check decrypt m1 = c^d mod N */
start = clock();
/* Use standard non-constant-time modexp with private exponent
=> faster but vulnerable to simple power attack (SPA) */
bdModExp(y, c, d, N);
finish = clock();
tinv = (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("y=c^d mod N (standard)\n", y, "\n");
isequal = bdCompare_ct(y, m);
printf("Decryption %s\n", (isequal == 0 ? "OK" : "FAILED!"));
assert(isequal == 0);
printf("Decryption by standard modexp took %.3f secs\n", tinv);
/* Now decrypt using constant-time modexp */
start = clock();
/* Resistant to simple power attack, but not differential power analysis (DPA) */
bdModExp_ct(y, c, d, N);
finish = clock();
tinv_ct = (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("y=c^d mod N (constant-time)\n", y, "\n");
isequal = bdCompare_ct(y, m);
printf("Decryption %s\n", (isequal == 0 ? "OK" : "FAILED!"));
assert(isequal == 0);
printf("Decryption by constant-time modexp took %.3f secs\n", tinv_ct);
printf("Ratio constant-time/standard = %.3f\n", tinv_ct / tinv);
/*
USE BLINDING TO DEFEAT DPA
Differential power analysis depends on the attacker knowing the base c of the exponentiation.
This can succeed even if constant-time exponentiation is used.
Ref: Jean-Sebastian Coron, "Resistance Against Differential Power Analysis for
Elliptic Curve Cryptosystems", August 1999.
-- This version adapted from Coron's elliptic curve point scalar multiplication
to RSA-style modular exponentiation.
*/
/* Algorithm: Modular exponentiation with blinding.
Input: RSA ciphertext c, private exponent d, public exponent e, modulus N
Output: RSA plaintext c^d mod N
1. Select a random integer r < N with gcd(r,N) = 1
2. Compute R = r^e mod N and S = r^-1 mod N
3. Compute x = c.R mod N
4. Compute z = x^d mod N
5. Compute y = S.z mod N
6. Return y
*/
/*
You could store the values R and S initially and refresh on each execution by
R <-- R^{2(-1)^b}
S <-- S^{2(-1)^b}
where b is a random bit generated at each new execution.
*/
printf("\nUSING BLINDING...\n");
start = clock();
printf("1. Select a random integer r < N with gcd(r,N) = 1 \n");
do {
bdRandomBits(r, nbits);
bdModulo(r, r, N);
bdGcd(g, r, N);
} while (bdShortCmp(g, 1) != 0);
bdPrintHex("r=", r, "\n");
bdPrintHex("[CHECK] gcd(r,n)=", g, "\n");
printf("2. Compute R = r^e mod N and S = r^-1 mod N \n");
bdModExp(R, r, e, N); /* NB public exponent, so no need for CT */
bdModInv(S, r, N);
bdPrintHex("R=r^e mod N=", R, "\n");
bdPrintHex("S=r^-1 mod N=", S, "\n");
printf("3. Compute x = c.R mod N \n");
bdModMult(x, c, R, N);
bdPrintHex("x = c.R mod N=", x, "\n");
printf("4. Compute z = x^d mod N \n");
bdModExp_ct(z, x, d, N);
bdPrintHex("z = b^d mod N=", z, "\n");
printf("5. Compute y = S.z mod N \n");
bdModMult(y, S, z, N);
bdPrintHex("y = S.z mod N=", y, "\n");
finish = clock(); /* Assume effect of printing is negligible (?) */
tblind = (double)(finish - start) / CLOCKS_PER_SEC;
printf("6. Return y = c^d mod N \n");
isequal = bdCompare_ct(y, m);
printf("Decryption %s\n", (isequal == 0 ? "OK" : "FAILED!"));
assert(isequal == 0);
printf("Decryption using blinding took %.3f secs\n", tblind);
printf("Ratio blinding/standard (with printing) = %.3f\n", tblind / tinv);
printf("\nREPEAT WITH REFRESHED R AND S...\n");
tblind = 0;
for (i = 0; i < ntimes; i++) {
printf("Iteration number %d:\n", i+1);
/* Generate a random bit */
b = bdRandDigit() & 0x1;
printf("Random bit b=%d\n", b);
start = clock();
/* R <-- R^{2(-1)^b}, S <-- S^{2(-1)^b} */
bdModMult(R, R, R, N);
bdModMult(S, S, S, N);
if (b) {
bdModInv(R, R, N);
bdModInv(S, S, N);
}
/* 3. Compute x = c.R mod N */
bdModMult(x, c, R, N);
/* 4. Compute z = x^d mod N */
bdModExp_ct(z, x, d, N);
/* 5. Compute y = S.z mod N */
bdModMult(y, S, z, N);
finish = clock();
tblind += (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("R <-- R^{2(-1)^b}=\n", R, "\n");
bdPrintHex("S <-- S^{2(-1)^b}=\n", S, "\n");
/* 6. Return y = c^d mod N */
bdPrintHex("Output y=\n", y, "\n");
isequal = bdCompare_ct(y, m);
printf("Decryption %s\n", (isequal == 0 ? "OK" : "FAILED!"));
assert(isequal == 0);
printf("\n");
}
tblind /= ntimes;
printf("Decryption using blinding took on average %.3f secs over %d repeats\n", tblind, ntimes);
printf("Ratio blinding/standard = %.3f\n", tblind / tinv);
/* Clean up */
bdFreeVars(&N, &e, &d, &m, &c, &y, &r, &g, &R, &S, &x, &z);
printf("\nOK, SUCCESSFULLY COMPLETED TESTS WITHOUT ERROR.\n");
return 0;
}
*/
bdConvFromHex(N, "E08973398DD8F5F5E88776397F4EB005BB5383DE0FB7ABDC7DC775290D052E6D12DFA68626D4D26FAA5829FC97ECFA82510F3080BEB1509E4644F12CBBD832CFC6686F07D9B060ACBEEE34096A13F5F7050593DF5EBA3556D961FF197FC981E6F86CEA874070EFAC6D2C749F2DFA553AB9997702A648528C4EF357385774575F");
bdConvFromHex(e, "010001");
bdConvFromHex(d, "A403C327477634346CA686B57949014B2E8AD2C862B2C7D748096A8B91F736F275D6E8CD15906027314735644D95CD6763CEB49F56AC2F376E1CEE0EBF282DF439906F34D86E085BD5656AD841F313D72D395EFE33CBFF29E4030B3D05A28FB7F18EA27637B07957D32F2BDE8706227D04665EC91BAF8B1AC3EC9144AB7F21");
printf("Public key:\n");
bdPrintHex("N=", N, "\n");
bdPrintHex("e=", e, "\n");
printf("Private key:\n");
bdPrintHex("d=", d, "\n");
nbits = bdBitLength(N);
printf("Key size = %d bits\n", nbits);
/* Set a random message m < N */
bdQuickRandBits(m, nbits-8);
bdPrintHex("Random plaintext m =\n", m, "\n");
/* Encrypt c = m^e mod N */
/* NB no need to use constant-time modexp when using public exponent */
bdModExp(c, m, e, N);
bdPrintHex("Ciphertext c=m^e mod N=\n", c, "\n");
printf("\nSIMPLE DECRYPTION USING PRIVATE EXPONENT...\n");
/* Check decrypt m1 = c^d mod N */
start = clock();
/* Use standard non-constant-time modexp with private exponent
=> faster but vulnerable to simple power attack (SPA) */
bdModExp(y, c, d, N);
finish = clock();
tinv = (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("y=c^d mod N (standard)\n", y, "\n");
isequal = bdCompare_ct(y, m);
printf("Decryption %s\n", (isequal == 0 ? "OK" : "FAILED!"));
assert(isequal == 0);
printf("Decryption by standard modexp took %.3f secs\n", tinv);
/* Now decrypt using constant-time modexp */
start = clock();
/* Resistant to simple power attack, but not differential power analysis (DPA) */
bdModExp_ct(y, c, d, N);
finish = clock();
tinv_ct = (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("y=c^d mod N (constant-time)\n", y, "\n");
isequal = bdCompare_ct(y, m);
printf("Decryption %s\n", (isequal == 0 ? "OK" : "FAILED!"));
assert(isequal == 0);
printf("Decryption by constant-time modexp took %.3f secs\n", tinv_ct);
printf("Ratio constant-time/standard = %.3f\n", tinv_ct / tinv);
/*
USE BLINDING TO DEFEAT DPA
Differential power analysis depends on the attacker knowing the base c of the exponentiation.
This can succeed even if constant-time exponentiation is used.
Ref: Jean-Sebastian Coron, "Resistance Against Differential Power Analysis for
Elliptic Curve Cryptosystems", August 1999.
-- This version adapted from Coron's elliptic curve point scalar multiplication
to RSA-style modular exponentiation.
*/
/* Algorithm: Modular exponentiation with blinding.
Input: RSA ciphertext c, private exponent d, public exponent e, modulus N
Output: RSA plaintext c^d mod N
1. Select a random integer r < N with gcd(r,N) = 1
2. Compute R = r^e mod N and S = r^-1 mod N
3. Compute x = c.R mod N
4. Compute z = x^d mod N
5. Compute y = S.z mod N
6. Return y
*/
/*
You could store the values R and S initially and refresh on each execution by
R <-- R^{2(-1)^b}
S <-- S^{2(-1)^b}
where b is a random bit generated at each new execution.
*/
printf("\nUSING BLINDING...\n");
start = clock();
printf("1. Select a random integer r < N with gcd(r,N) = 1 \n");
do {
bdRandomBits(r, nbits);
bdModulo(r, r, N);
bdGcd(g, r, N);
} while (bdShortCmp(g, 1) != 0);
bdPrintHex("r=", r, "\n");
bdPrintHex("[CHECK] gcd(r,n)=", g, "\n");
printf("2. Compute R = r^e mod N and S = r^-1 mod N \n");
bdModExp(R, r, e, N); /* NB public exponent, so no need for CT */
bdModInv(S, r, N);
bdPrintHex("R=r^e mod N=", R, "\n");
bdPrintHex("S=r^-1 mod N=", S, "\n");
printf("3. Compute x = c.R mod N \n");
bdModMult(x, c, R, N);
bdPrintHex("x = c.R mod N=", x, "\n");
printf("4. Compute z = x^d mod N \n");
bdModExp_ct(z, x, d, N);
bdPrintHex("z = b^d mod N=", z, "\n");
printf("5. Compute y = S.z mod N \n");
bdModMult(y, S, z, N);
bdPrintHex("y = S.z mod N=", y, "\n");
finish = clock(); /* Assume effect of printing is negligible (?) */
tblind = (double)(finish - start) / CLOCKS_PER_SEC;
printf("6. Return y = c^d mod N \n");
isequal = bdCompare_ct(y, m);
printf("Decryption %s\n", (isequal == 0 ? "OK" : "FAILED!"));
assert(isequal == 0);
printf("Decryption using blinding took %.3f secs\n", tblind);
printf("Ratio blinding/standard (with printing) = %.3f\n", tblind / tinv);
printf("\nREPEAT WITH REFRESHED R AND S...\n");
tblind = 0;
for (i = 0; i < ntimes; i++) {
printf("Iteration number %d:\n", i+1);
/* Generate a random bit */
b = bdRandDigit() & 0x1;
printf("Random bit b=%d\n", b);
start = clock();
/* R <-- R^{2(-1)^b}, S <-- S^{2(-1)^b} */
bdModMult(R, R, R, N);
bdModMult(S, S, S, N);
if (b) {
bdModInv(R, R, N);
bdModInv(S, S, N);
}
/* 3. Compute x = c.R mod N */
bdModMult(x, c, R, N);
/* 4. Compute z = x^d mod N */
bdModExp_ct(z, x, d, N);
/* 5. Compute y = S.z mod N */
bdModMult(y, S, z, N);
finish = clock();
tblind += (double)(finish - start) / CLOCKS_PER_SEC;
bdPrintHex("R <-- R^{2(-1)^b}=\n", R, "\n");
bdPrintHex("S <-- S^{2(-1)^b}=\n", S, "\n");
/* 6. Return y = c^d mod N */
bdPrintHex("Output y=\n", y, "\n");
isequal = bdCompare_ct(y, m);
printf("Decryption %s\n", (isequal == 0 ? "OK" : "FAILED!"));
assert(isequal == 0);
printf("\n");
}
tblind /= ntimes;
printf("Decryption using blinding took on average %.3f secs over %d repeats\n", tblind, ntimes);
printf("Ratio blinding/standard = %.3f\n", tblind / tinv);
/* Clean up */
bdFreeVars(&N, &e, &d, &m, &c, &y, &r, &g, &R, &S, &x, &z);
printf("\nOK, SUCCESSFULLY COMPLETED TESTS WITHOUT ERROR.\n");
return 0;
}

View File

@ -1,124 +1,124 @@
/* $Id: t_bdRandomOctets.c $ */
/* Examples using the `bigdRand` functions:
bdRandomOctets()
bdRandomSeeded()
bdRandomNumber()
*/
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#include <stdio.h>
#include <assert.h>
#include <math.h> // For sqrt in statistics
#include "bigd.h"
#include "bigdRand.h"
#define TEST_LEN 24
#define TEST_N 32
#define NTESTS (TEST_N * 10)
static void pr_byteshex(const char *prefix, const unsigned char *bytes, size_t nbytes, const char *suffix)
{
size_t i;
if (prefix) printf("%s", prefix);
for (i = 0; i < nbytes; i++)
{
printf("%02X", bytes[i]);
}
if (suffix) printf("%s", suffix);
}
int main(void)
{
unsigned char bytes[TEST_LEN];
size_t nbytes;
int ntests, itest, i;
BIGD a, p, N;
int score[TEST_N] = { 0 };
int t;
BIGD temp;
int themin, themax;
double mean, var, sd;
ntests = TEST_LEN;
printf("Testing bdRandomOctets...\n");
for (itest = 0; itest < ntests; itest++)
{
//printf("Test %d...\n", itest+1);
nbytes = TEST_LEN - itest;
bdRandomOctets(bytes, nbytes, NULL, 0);
pr_byteshex("", bytes, nbytes, "\n");
}
// Now test bdRandomSeeded calling internal fn bdRandomOctets
printf("Testing bdRandomSeeded with bdRandomOctets()...\n");
a = bdNew();
for (i = 0; i < 10; i++)
{
bdRandomSeeded(a, 128, NULL, 0, bdRandomOctets);
bdPrintHex("r=", a, "\n");
}
// And generate some primes
printf("Generating primes with bdGeneratePrime() calling bdRandomOctets()...\n");
p = bdNew();
for (i = 0; i < 4; i++)
{
bdGeneratePrime(p, 256, 128, NULL, 0, bdRandomOctets);
bdPrintHex("p=", p, "\n");
}
// Generate some random numbers in the range [0,N-1] where N = 32
// (and keep score of count for each value)
temp = bdNew();
N = bdNew();
bdSetShort(N, TEST_N);
bdPrintDecimal("Random numbers in the range [0,N-1] computed by bdRandomNumber(N), N=", N, ":\n");
for (i = 0; i < NTESTS; i++)
{
bdRandomNumber(a, N);
bdPrintDecimal("", a, " ");
/* Convert BIGD into an int */
t = (int)bdShortMod(temp, a, 0xFFFFFFFF);
assert(0 <= t && t < TEST_N);
score[t] += 1;
}
printf("\n");
printf("[Statistics] Distribution over %d tests (EV=%.1f):\n", NTESTS, (double)NTESTS / TEST_N);
mean = var = 0.0;
themin = 99999;
themax = 0;
for (i = 0; i < TEST_N; i++)
{
int v = score[i];
printf("%d ", v);
if (v > themax) themax = v;
if (v < themin) themin = v;
mean += (double)v;
var += v * v;
}
printf("\n");
mean /= TEST_N;
var = var / TEST_N - mean*mean;
sd = sqrt(var);
printf("mean=%.3f sd=%.3f min=%d (%.2f sd) max=%d (%+.2f sd)\n",
mean, sd, themin, (themin-mean)/sd, themax, (themax-mean)/sd);
return 0;
}
/* $Id: t_bdRandomOctets.c $ */
/* Examples using the `bigdRand` functions:
bdRandomOctets()
bdRandomSeeded()
bdRandomNumber()
*/
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#include <stdio.h>
#include <assert.h>
#include <math.h> // For sqrt in statistics
#include "bigd.h"
#include "bigdRand.h"
#define TEST_LEN 24
#define TEST_N 32
#define NTESTS (TEST_N * 10)
static void pr_byteshex(const char *prefix, const unsigned char *bytes, size_t nbytes, const char *suffix)
{
size_t i;
if (prefix) printf("%s", prefix);
for (i = 0; i < nbytes; i++)
{
printf("%02X", bytes[i]);
}
if (suffix) printf("%s", suffix);
}
int main(void)
{
unsigned char bytes[TEST_LEN];
size_t nbytes;
int ntests, itest, i;
BIGD a, p, N;
int score[TEST_N] = { 0 };
int t;
BIGD temp;
int themin, themax;
double mean, var, sd;
ntests = TEST_LEN;
printf("Testing bdRandomOctets...\n");
for (itest = 0; itest < ntests; itest++)
{
//printf("Test %d...\n", itest+1);
nbytes = TEST_LEN - itest;
bdRandomOctets(bytes, nbytes, NULL, 0);
pr_byteshex("", bytes, nbytes, "\n");
}
// Now test bdRandomSeeded calling internal fn bdRandomOctets
printf("Testing bdRandomSeeded with bdRandomOctets()...\n");
a = bdNew();
for (i = 0; i < 10; i++)
{
bdRandomSeeded(a, 128, NULL, 0, bdRandomOctets);
bdPrintHex("r=", a, "\n");
}
// And generate some primes
printf("Generating primes with bdGeneratePrime() calling bdRandomOctets()...\n");
p = bdNew();
for (i = 0; i < 4; i++)
{
bdGeneratePrime(p, 256, 128, NULL, 0, bdRandomOctets);
bdPrintHex("p=", p, "\n");
}
// Generate some random numbers in the range [0,N-1] where N = 32
// (and keep score of count for each value)
temp = bdNew();
N = bdNew();
bdSetShort(N, TEST_N);
bdPrintDecimal("Random numbers in the range [0,N-1] computed by bdRandomNumber(N), N=", N, ":\n");
for (i = 0; i < NTESTS; i++)
{
bdRandomNumber(a, N);
bdPrintDecimal("", a, " ");
/* Convert BIGD into an int */
t = (int)bdShortMod(temp, a, 0xFFFFFFFF);
assert(0 <= t && t < TEST_N);
score[t] += 1;
}
printf("\n");
printf("[Statistics] Distribution over %d tests (EV=%.1f):\n", NTESTS, (double)NTESTS / TEST_N);
mean = var = 0.0;
themin = 99999;
themax = 0;
for (i = 0; i < TEST_N; i++)
{
int v = score[i];
printf("%d ", v);
if (v > themax) themax = v;
if (v < themin) themin = v;
mean += (double)v;
var += v * v;
}
printf("\n");
mean /= TEST_N;
var = var / TEST_N - mean*mean;
sd = sqrt(var);
printf("mean=%.3f sd=%.3f min=%d (%.2f sd) max=%d (%+.2f sd)\n",
mean, sd, themin, (themin-mean)/sd, themax, (themax-mean)/sd);
return 0;
}

View File

@ -1,156 +1,156 @@
/* $Id: t_bdRsaCrack.c $ */
/*
This code uses the free BIGDIGITS library version 2.3 available from
http://di-mgt.com.au/bigdigits.html
to show how the Chinese Remainder Theorem and Gauss's Method can be used
to find a message encrypted by the RSA algorithm without having to factor
the modulus. The same message must have been encrypted with public exponent
e = 3 to three different recipients without any random padding.
Ref: http://www.di-mgt.com.au/crt.html#crackingrsa
Copyright (C) 2011 DI Management Services Pty Ltd. All rights reserved.
*/
/*
Last updated:
$Date: 2011-11-11 11:11:11 $
$Author: dai $
*/
#include <stdio.h>
#include "bigd.h"
int debug = 0;
int main(void)
{
BIGD m, e, n1, n2, n3, c1, c2, c3, N, N1, N2, N3, d1, d2, d3, s, t, x;
m = bdNew();
e = bdNew();
n1 = bdNew();
n2 = bdNew();
n3 = bdNew();
c1 = bdNew();
c2 = bdNew();
c3 = bdNew();
N = bdNew();
N1 = bdNew();
N2 = bdNew();
N3 = bdNew();
d1 = bdNew();
d2 = bdNew();
d3 = bdNew();
s = bdNew();
t = bdNew();
x = bdNew();
/* Read in modulus values for three 512-bit public keys */
bdConvFromHex(n1, "A9C737DD808D02866FBF1ACF05DE2EB124137007A4965EC4DCBFA6D02F97E0123A8FD3691E414A1382F38AB39B09975705ECEAF1131A283C937B309F1C1417F9");
bdConvFromHex(n2, "B7E9E114A08ADFF12F762D7F0E1F16202E1EB7A7F2852369BDF44865783D19111E6D61B31DE987BCB9775099E220A798D4F99CD3E5F04C64F87A35C0268A83E9");
bdConvFromHex(n3, "C2BDBD4E36BA20D37D5D1E968F09F2FC7B41A97F3052274E4892D50D5FB337C923048AED7D393135EE55711E5C74975867F13D3845BAC9588B4BE170D08BAB57");
//bdSetShort(n1, 87);
//bdSetShort(n2, 115);
//bdSetShort(n3, 187);
printf("Three public modulus values, 512 bits each...\n");
bdPrintHex("n1=", n1, "\n");
bdPrintHex("n2=", n2, "\n");
bdPrintHex("n3=", n3, "\n");
/* The three public keys all have public exponent e = 3 */
bdSetShort(e, 3);
bdPrintHex("e=", e, "\n");
/* Set the common message m with no random padding (but large enough so m^3 > n_i) */
bdConvFromHex(m, "02ffffffffffffffffffffffffffffffffffffffffff0000deadbeefcafe");
//bdSetShort(m, 10);
printf("Message to be encrypted...\n");
bdPrintHex("m=", m, "\n");
/* Create three ciphertexts, c_i = m^e mod n_i */
bdModExp(c1, m, e, n1);
bdModExp(c2, m, e, n2);
bdModExp(c3, m, e, n3);
printf("Three ciphertexts...\n");
bdPrintHex("c1=", c1, "\n");
bdPrintHex("c2=", c2, "\n");
bdPrintHex("c3=", c3, "\n");
/* An eavedropper has the public values n1, n2, n3, c1, c2 and c3 */
/* Check that n1, n2, n3 are coprime in pairs */
bdGcd(t, n1, n2);
bdPrintHex("gcd(n1,n2)=", t, "\n");
bdGcd(t, n2, n3);
bdPrintHex("gcd(n2,n3)=", t, "\n");
bdGcd(t, n3, n1);
bdPrintHex("gcd(n3,n1)=", t, "\n");
/* Compute N = n1 * n2 * n3 */
bdMultiply(t, n1, n2);
bdMultiply(N, t, n3);
if (debug) bdPrintDecimal("N=", N, "\n");
/* Compute N_i = N/n_i for i = 1,2,3 */
bdMultiply(N1, n2, n3);
bdMultiply(N2, n1, n3);
bdMultiply(N3, n1, n2);
if (debug) bdPrintDecimal("N1=", N1, "\n");
if (debug) bdPrintDecimal("N2=", N2, "\n");
if (debug) bdPrintDecimal("N3=", N3, "\n");
/* Compute d_i = N_i^{-1} mod n_i for i = 1,2,3 */
bdModInv(d1, N1, n1);
bdModInv(d2, N2, n2);
bdModInv(d3, N3, n3);
if (debug) bdPrintDecimal("d1=", d1, "\n");
if (debug) bdPrintDecimal("d2=", d2, "\n");
if (debug) bdPrintDecimal("d3=", d3, "\n");
/* Compute x = c_1 N_1 d_1 + c_2 N_2 d_2 + c_3 N_3 d_3 (mod N) */
bdModMult(s, c1, N1, N);
bdModMult(x, s, d1, N);
bdModMult(s, c2, N2, N);
bdModMult(t, s, d2, N);
bdAdd_s(x, x, t);
bdModMult(s, c3, N3, N);
bdModMult(t, s, d3, N);
bdAdd_s(s, x, t);
bdModulo(x, s, N);
printf("Computed value of x = c_1 N_1 d_1 + c_2 N_2 d_2 + c_3 N_3 d_3 (mod N)...\n");
bdPrintHex("x=", x, "\n");
/* Compute the integer cube root of x */
bdCubeRoot(t, x);
bdPrintHex("m'=cuberoot(x)=", t, "\n");
/* Do we have the correct answer? */
if (bdCompare(t, m) == 0)
printf("HOORAY! We have found the correct answer, m' = m.\n");
else
printf("OH BU**AR! We didn't find the correct answer.\n");
//clean_up:
bdFree(&m);
bdFree(&e);
bdFree(&n1);
bdFree(&n2);
bdFree(&n3);
bdFree(&c1);
bdFree(&c2);
bdFree(&c3);
bdFree(&N);
bdFree(&N1);
bdFree(&N2);
bdFree(&N3);
bdFree(&d1);
bdFree(&d2);
bdFree(&d3);
bdFree(&s);
bdFree(&t);
bdFree(&x);
return 0;
}
/* $Id: t_bdRsaCrack.c $ */
/*
This code uses the free BIGDIGITS library version 2.3 available from
http://di-mgt.com.au/bigdigits.html
to show how the Chinese Remainder Theorem and Gauss's Method can be used
to find a message encrypted by the RSA algorithm without having to factor
the modulus. The same message must have been encrypted with public exponent
e = 3 to three different recipients without any random padding.
Ref: http://www.di-mgt.com.au/crt.html#crackingrsa
Copyright (C) 2011 DI Management Services Pty Ltd. All rights reserved.
*/
/*
Last updated:
$Date: 2011-11-11 11:11:11 $
$Author: dai $
*/
#include <stdio.h>
#include "bigd.h"
int debug = 0;
int main(void)
{
BIGD m, e, n1, n2, n3, c1, c2, c3, N, N1, N2, N3, d1, d2, d3, s, t, x;
m = bdNew();
e = bdNew();
n1 = bdNew();
n2 = bdNew();
n3 = bdNew();
c1 = bdNew();
c2 = bdNew();
c3 = bdNew();
N = bdNew();
N1 = bdNew();
N2 = bdNew();
N3 = bdNew();
d1 = bdNew();
d2 = bdNew();
d3 = bdNew();
s = bdNew();
t = bdNew();
x = bdNew();
/* Read in modulus values for three 512-bit public keys */
bdConvFromHex(n1, "A9C737DD808D02866FBF1ACF05DE2EB124137007A4965EC4DCBFA6D02F97E0123A8FD3691E414A1382F38AB39B09975705ECEAF1131A283C937B309F1C1417F9");
bdConvFromHex(n2, "B7E9E114A08ADFF12F762D7F0E1F16202E1EB7A7F2852369BDF44865783D19111E6D61B31DE987BCB9775099E220A798D4F99CD3E5F04C64F87A35C0268A83E9");
bdConvFromHex(n3, "C2BDBD4E36BA20D37D5D1E968F09F2FC7B41A97F3052274E4892D50D5FB337C923048AED7D393135EE55711E5C74975867F13D3845BAC9588B4BE170D08BAB57");
//bdSetShort(n1, 87);
//bdSetShort(n2, 115);
//bdSetShort(n3, 187);
printf("Three public modulus values, 512 bits each...\n");
bdPrintHex("n1=", n1, "\n");
bdPrintHex("n2=", n2, "\n");
bdPrintHex("n3=", n3, "\n");
/* The three public keys all have public exponent e = 3 */
bdSetShort(e, 3);
bdPrintHex("e=", e, "\n");
/* Set the common message m with no random padding (but large enough so m^3 > n_i) */
bdConvFromHex(m, "02ffffffffffffffffffffffffffffffffffffffffff0000deadbeefcafe");
//bdSetShort(m, 10);
printf("Message to be encrypted...\n");
bdPrintHex("m=", m, "\n");
/* Create three ciphertexts, c_i = m^e mod n_i */
bdModExp(c1, m, e, n1);
bdModExp(c2, m, e, n2);
bdModExp(c3, m, e, n3);
printf("Three ciphertexts...\n");
bdPrintHex("c1=", c1, "\n");
bdPrintHex("c2=", c2, "\n");
bdPrintHex("c3=", c3, "\n");
/* An eavedropper has the public values n1, n2, n3, c1, c2 and c3 */
/* Check that n1, n2, n3 are coprime in pairs */
bdGcd(t, n1, n2);
bdPrintHex("gcd(n1,n2)=", t, "\n");
bdGcd(t, n2, n3);
bdPrintHex("gcd(n2,n3)=", t, "\n");
bdGcd(t, n3, n1);
bdPrintHex("gcd(n3,n1)=", t, "\n");
/* Compute N = n1 * n2 * n3 */
bdMultiply(t, n1, n2);
bdMultiply(N, t, n3);
if (debug) bdPrintDecimal("N=", N, "\n");
/* Compute N_i = N/n_i for i = 1,2,3 */
bdMultiply(N1, n2, n3);
bdMultiply(N2, n1, n3);
bdMultiply(N3, n1, n2);
if (debug) bdPrintDecimal("N1=", N1, "\n");
if (debug) bdPrintDecimal("N2=", N2, "\n");
if (debug) bdPrintDecimal("N3=", N3, "\n");
/* Compute d_i = N_i^{-1} mod n_i for i = 1,2,3 */
bdModInv(d1, N1, n1);
bdModInv(d2, N2, n2);
bdModInv(d3, N3, n3);
if (debug) bdPrintDecimal("d1=", d1, "\n");
if (debug) bdPrintDecimal("d2=", d2, "\n");
if (debug) bdPrintDecimal("d3=", d3, "\n");
/* Compute x = c_1 N_1 d_1 + c_2 N_2 d_2 + c_3 N_3 d_3 (mod N) */
bdModMult(s, c1, N1, N);
bdModMult(x, s, d1, N);
bdModMult(s, c2, N2, N);
bdModMult(t, s, d2, N);
bdAdd_s(x, x, t);
bdModMult(s, c3, N3, N);
bdModMult(t, s, d3, N);
bdAdd_s(s, x, t);
bdModulo(x, s, N);
printf("Computed value of x = c_1 N_1 d_1 + c_2 N_2 d_2 + c_3 N_3 d_3 (mod N)...\n");
bdPrintHex("x=", x, "\n");
/* Compute the integer cube root of x */
bdCubeRoot(t, x);
bdPrintHex("m'=cuberoot(x)=", t, "\n");
/* Do we have the correct answer? */
if (bdCompare(t, m) == 0)
printf("HOORAY! We have found the correct answer, m' = m.\n");
else
printf("OH BU**AR! We didn't find the correct answer.\n");
//clean_up:
bdFree(&m);
bdFree(&e);
bdFree(&n1);
bdFree(&n2);
bdFree(&n3);
bdFree(&c1);
bdFree(&c2);
bdFree(&c3);
bdFree(&N);
bdFree(&N1);
bdFree(&N2);
bdFree(&N3);
bdFree(&d1);
bdFree(&d2);
bdFree(&d3);
bdFree(&s);
bdFree(&t);
bdFree(&x);
return 0;
}

View File

@ -1,226 +1,226 @@
/* $Id: t_bdRsaFactorN.c $ */
/*
This code uses the free BIGDIGITS library version 2.3 available from
http://di-mgt.com.au/bigdigits.html
to show how to factor the RSA modulus n given the secret exponent d
Copyright (C) 2012 DI Management Services Pty Ltd. All rights reserved.
*/
/*
Last updated:
$Date: 2012-12-24 16:13 $
$Revision: 1.0.1 $
$Author: dai $
*/
#include <stdio.h>
#include "bigd.h"
int debug = 1;
#define DBDPRINT(pre, x, post) if(debug)bdPrintDecimal((pre),(x),(post))
const int primes[] = {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
};
#define NPRIMES (sizeof(primes)/sizeof(primes[0]))
int find_factors_of_n(BIGD p, BIGD q, BIGD n, BIGD e, BIGD d)
{
BIGD k, t, g, x, y, r;
int i, isdone;
k = bdNew();
t = bdNew();
g = bdNew();
x = bdNew();
y = bdNew();
r = bdNew();
bdSetZero(p);
bdSetZero(q);
/* 1. [Initialize] Set k <-- de - 1 */
bdMultiply(k, d, e);
bdDecrement(k);
DBDPRINT("k=de-1=", k, "\n");
/* 2. [Try a random g] Choose g at random from {2, ..., N-1} */
/* (we cheat a bit here and just try the first primes in order) */
for (isdone = 0, i = 0; !isdone && i < NPRIMES; i++)
{
bdSetShort(g, primes[i]);
DBDPRINT("Trying g=", g, "\n");
/* Set t <-- k */
bdSetEqual(t, k);
/* 3. [Next t] If t is divisible by 2 ... */
while (bdIsEven(t))
{
/* Set t <-- t / 2 */
bdShiftRight(t, t, 1);
DBDPRINT("t=", t, "\n");
/* Set x = g^t mod N */
bdModExp(x, g, t, n);
DBDPRINT("x=g^t mod N=", x, "\n");
/* 4. [Finished?] If x > 1 and y = gcd(x-1, N)
then set p <-- y and q <-- N/y, output (p,q) and stop.
*/
if (bdShortCmp(x, 1) > 0)
{
bdDecrement(x);
bdGcd(y, x, n);
DBDPRINT("y=gcd(x-1,N)=", y, "\n");
if (bdShortCmp(y, 1) > 0)
{ /* We have it */
bdSetEqual(p, y);
bdDivide(q, r, n, y);
isdone = 1;
break;
}
}
} /* 4a. ... otherwise go to step 3. */
} /* 3a. ... otherwise go to step 2. */
/* Finally, to be consistent with convention, we make sure p > q */
if (isdone && bdCompare(p, q) < 0)
{
bdSetEqual(r, p);
bdSetEqual(p, q);
bdSetEqual(q, r);
}
bdFree(&k);
bdFree(&t);
bdFree(&g);
bdFree(&x);
bdFree(&y);
bdFree(&r);
return isdone;
}
void test_simple(void)
{
BIGD n, e, d, p, q;
n = bdNew();
e = bdNew();
d = bdNew();
p = bdNew();
q = bdNew();
bdSetShort(n, 25777);
bdSetShort(e, 3);
bdSetShort(d, 16971);
printf("Input:\n");
bdPrintDecimal("n=", n, "\n");
bdPrintDecimal("e=", e, "\n");
bdPrintDecimal("d=", d, "\n");
find_factors_of_n(p, q, n, e, d);
printf("Output:\n");
bdPrintDecimal("p=", p, "\n");
bdPrintDecimal("q=", q, "\n");
//clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
}
void test_508(void)
{
BIGD n, e, d, p, q;
n = bdNew();
e = bdNew();
d = bdNew();
p = bdNew();
q = bdNew();
/*
Using 508-bit RSA key from
"Some Examples of the PKCS Standards"
An RSA Laboratories Technical Note,
Burton S. Kaliski Jr., November 1, 1993
/* $Id: t_bdRsaFactorN.c $ */
/*
This code uses the free BIGDIGITS library version 2.3 available from
http://di-mgt.com.au/bigdigits.html
to show how to factor the RSA modulus n given the secret exponent d
Copyright (C) 2012 DI Management Services Pty Ltd. All rights reserved.
*/
/*
Last updated:
$Date: 2012-12-24 16:13 $
$Revision: 1.0.1 $
$Author: dai $
*/
#include <stdio.h>
#include "bigd.h"
int debug = 1;
#define DBDPRINT(pre, x, post) if(debug)bdPrintDecimal((pre),(x),(post))
const int primes[] = {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
};
#define NPRIMES (sizeof(primes)/sizeof(primes[0]))
int find_factors_of_n(BIGD p, BIGD q, BIGD n, BIGD e, BIGD d)
{
BIGD k, t, g, x, y, r;
int i, isdone;
k = bdNew();
t = bdNew();
g = bdNew();
x = bdNew();
y = bdNew();
r = bdNew();
bdSetZero(p);
bdSetZero(q);
/* 1. [Initialize] Set k <-- de - 1 */
bdMultiply(k, d, e);
bdDecrement(k);
DBDPRINT("k=de-1=", k, "\n");
/* 2. [Try a random g] Choose g at random from {2, ..., N-1} */
/* (we cheat a bit here and just try the first primes in order) */
for (isdone = 0, i = 0; !isdone && i < NPRIMES; i++)
{
bdSetShort(g, primes[i]);
DBDPRINT("Trying g=", g, "\n");
/* Set t <-- k */
bdSetEqual(t, k);
/* 3. [Next t] If t is divisible by 2 ... */
while (bdIsEven(t))
{
/* Set t <-- t / 2 */
bdShiftRight(t, t, 1);
DBDPRINT("t=", t, "\n");
/* Set x = g^t mod N */
bdModExp(x, g, t, n);
DBDPRINT("x=g^t mod N=", x, "\n");
/* 4. [Finished?] If x > 1 and y = gcd(x-1, N)
then set p <-- y and q <-- N/y, output (p,q) and stop.
*/
if (bdShortCmp(x, 1) > 0)
{
bdDecrement(x);
bdGcd(y, x, n);
DBDPRINT("y=gcd(x-1,N)=", y, "\n");
if (bdShortCmp(y, 1) > 0)
{ /* We have it */
bdSetEqual(p, y);
bdDivide(q, r, n, y);
isdone = 1;
break;
}
}
} /* 4a. ... otherwise go to step 3. */
} /* 3a. ... otherwise go to step 2. */
/* Finally, to be consistent with convention, we make sure p > q */
if (isdone && bdCompare(p, q) < 0)
{
bdSetEqual(r, p);
bdSetEqual(p, q);
bdSetEqual(q, r);
}
bdFree(&k);
bdFree(&t);
bdFree(&g);
bdFree(&x);
bdFree(&y);
bdFree(&r);
return isdone;
}
void test_simple(void)
{
BIGD n, e, d, p, q;
n = bdNew();
e = bdNew();
d = bdNew();
p = bdNew();
q = bdNew();
bdSetShort(n, 25777);
bdSetShort(e, 3);
bdSetShort(d, 16971);
printf("Input:\n");
bdPrintDecimal("n=", n, "\n");
bdPrintDecimal("e=", e, "\n");
bdPrintDecimal("d=", d, "\n");
find_factors_of_n(p, q, n, e, d);
printf("Output:\n");
bdPrintDecimal("p=", p, "\n");
bdPrintDecimal("q=", q, "\n");
//clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
}
void test_508(void)
{
BIGD n, e, d, p, q;
n = bdNew();
e = bdNew();
d = bdNew();
p = bdNew();
q = bdNew();
/*
Using 508-bit RSA key from
"Some Examples of the PKCS Standards"
An RSA Laboratories Technical Note,
Burton S. Kaliski Jr., November 1, 1993
p = 33 d4 84 45 c8 59 e5 23 40 de 70 4b cd da 06 5f bb 40 58
d7 40 bd 1d 67 d2 9e 9c 14 6c 11 cf 61
q = 33 5e 84 08 86 6b 0f d3 8d c7 00 2d 3f 97 2c 67 38 9a 65
d5 d8 30 65 66 d5 c4 f2 a5 aa 52 62 8b
*/
bdConvFromHex(n, "0a66791dc6988168de7ab77419bb7fb0c001c62710270075142942e19a8d8c51d053b3e3782a1de5dc5af4ebe99468170114a1dfe67cdc9a9af55d655620bbab");
bdConvFromHex(e, "010001");
bdConvFromHex(d, "0123c5b61ba36edb1d3679904199a89ea80c09b9122e1400c09adcf7784676d01d23356a7d44d6bd8bd50e94bfc723fa87d8862b75177691c11d757692df8881");
printf("Input:\n");
bdPrintHex("n=", n, "\n");
bdPrintHex("e=", e, "\n");
bdPrintHex("d=", d, "\n");
find_factors_of_n(p, q, n, e, d);
printf("Output:\n");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
//clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
}
void test_alice1024(void)
{
BIGD n, e, d, p, q;
n = bdNew();
e = bdNew();
d = bdNew();
p = bdNew();
q = bdNew();
/*
Using Alice's 1024-bit RSA key from [RFC4134]:
d5 d8 30 65 66 d5 c4 f2 a5 aa 52 62 8b
*/
bdConvFromHex(n, "0a66791dc6988168de7ab77419bb7fb0c001c62710270075142942e19a8d8c51d053b3e3782a1de5dc5af4ebe99468170114a1dfe67cdc9a9af55d655620bbab");
bdConvFromHex(e, "010001");
bdConvFromHex(d, "0123c5b61ba36edb1d3679904199a89ea80c09b9122e1400c09adcf7784676d01d23356a7d44d6bd8bd50e94bfc723fa87d8862b75177691c11d757692df8881");
printf("Input:\n");
bdPrintHex("n=", n, "\n");
bdPrintHex("e=", e, "\n");
bdPrintHex("d=", d, "\n");
find_factors_of_n(p, q, n, e, d);
printf("Output:\n");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
//clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
}
void test_alice1024(void)
{
BIGD n, e, d, p, q;
n = bdNew();
e = bdNew();
d = bdNew();
p = bdNew();
q = bdNew();
/*
Using Alice's 1024-bit RSA key from [RFC4134]:
Hoffman, P., Ed., "Examples of S/MIME Messages", RFC 4134, July 2005.
*/
bdConvFromHex(n, "E08973398DD8F5F5E88776397F4EB005BB5383DE0FB7ABDC7DC775290D052E6D12DFA68626D4D26FAA5829FC97ECFA82510F3080BEB1509E4644F12CBBD832CFC6686F07D9B060ACBEEE34096A13F5F7050593DF5EBA3556D961FF197FC981E6F86CEA874070EFAC6D2C749F2DFA553AB9997702A648528C4EF357385774575F");
bdConvFromHex(e, "010001");
bdConvFromHex(d, "A403C327477634346CA686B57949014B2E8AD2C862B2C7D748096A8B91F736F275D6E8CD15906027314735644D95CD6763CEB49F56AC2F376E1CEE0EBF282DF439906F34D86E085BD5656AD841F313D72D395EFE33CBFF29E4030B3D05A28FB7F18EA27637B07957D32F2BDE8706227D04665EC91BAF8B1AC3EC9144AB7F21");
// p = F6D6E022214C5F0A70FF27FCE5B3506A9DE50FB58596C640FAA80AB49B9B0C55C2011DF937828A14C8F2930E92CDA56621B93CD206BFB45531C9DCADCA982DD1
// q = E8DEB0112509D2025101DE8AE89850F5777761A445936B085596735DF4C85B129322738B7FD3707FF5A4AABB74FD3C226ADA38912A865B6C14E8AE4C9EFA8E2F
printf("Input:\n");
bdPrintHex("n=", n, "\n");
bdPrintHex("e=", e, "\n");
bdPrintHex("d=", d, "\n");
find_factors_of_n(p, q, n, e, d);
printf("Output:\n");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
//clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
}
int main(void)
{
test_simple();
test_508();
//test_alice1024();
return 0;
}
*/
bdConvFromHex(n, "E08973398DD8F5F5E88776397F4EB005BB5383DE0FB7ABDC7DC775290D052E6D12DFA68626D4D26FAA5829FC97ECFA82510F3080BEB1509E4644F12CBBD832CFC6686F07D9B060ACBEEE34096A13F5F7050593DF5EBA3556D961FF197FC981E6F86CEA874070EFAC6D2C749F2DFA553AB9997702A648528C4EF357385774575F");
bdConvFromHex(e, "010001");
bdConvFromHex(d, "A403C327477634346CA686B57949014B2E8AD2C862B2C7D748096A8B91F736F275D6E8CD15906027314735644D95CD6763CEB49F56AC2F376E1CEE0EBF282DF439906F34D86E085BD5656AD841F313D72D395EFE33CBFF29E4030B3D05A28FB7F18EA27637B07957D32F2BDE8706227D04665EC91BAF8B1AC3EC9144AB7F21");
// p = F6D6E022214C5F0A70FF27FCE5B3506A9DE50FB58596C640FAA80AB49B9B0C55C2011DF937828A14C8F2930E92CDA56621B93CD206BFB45531C9DCADCA982DD1
// q = E8DEB0112509D2025101DE8AE89850F5777761A445936B085596735DF4C85B129322738B7FD3707FF5A4AABB74FD3C226ADA38912A865B6C14E8AE4C9EFA8E2F
printf("Input:\n");
bdPrintHex("n=", n, "\n");
bdPrintHex("e=", e, "\n");
bdPrintHex("d=", d, "\n");
find_factors_of_n(p, q, n, e, d);
printf("Output:\n");
bdPrintHex("p=", p, "\n");
bdPrintHex("q=", q, "\n");
//clean_up:
bdFree(&n);
bdFree(&e);
bdFree(&d);
bdFree(&p);
bdFree(&q);
}
int main(void)
{
test_simple();
test_508();
//test_alice1024();
return 0;
}

View File

@ -1,58 +1,58 @@
/* $Id: t_bdSimple.c $ */
/* A very simple test of some "bd" functions */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#include <stdio.h>
#include "bigd.h"
int main(void)
{
BIGD u, v, w;
/* Display the BigDigits version number */
printf("BigDigits version=%d\n", bdVersion());
/* Create new BIGD objects */
u = bdNew();
v = bdNew();
w = bdNew();
/* Compute 2 * 0xdeadbeefface */
bdSetShort(u, 2);
bdConvFromHex(v, "deadbeefface");
bdMultiply(w, u, v);
/* Display the result */
bdPrintHex("", u, " * ");
bdPrintHex("0x", v, " = ");
bdPrintHex("0x", w, "\n");
/* and again in decimal format */
bdPrintDecimal("", u, " * ");
bdPrintDecimal("", v, " = ");
bdPrintDecimal("", w, "\n");
/* Free all objects we made */
bdFree(&u);
bdFree(&v);
bdFree(&w);
return 0;
}
/* $Id: t_bdSimple.c $ */
/* A very simple test of some "bd" functions */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#include <stdio.h>
#include "bigd.h"
int main(void)
{
BIGD u, v, w;
/* Display the BigDigits version number */
printf("BigDigits version=%d\n", bdVersion());
/* Create new BIGD objects */
u = bdNew();
v = bdNew();
w = bdNew();
/* Compute 2 * 0xdeadbeefface */
bdSetShort(u, 2);
bdConvFromHex(v, "deadbeefface");
bdMultiply(w, u, v);
/* Display the result */
bdPrintHex("", u, " * ");
bdPrintHex("0x", v, " = ");
bdPrintHex("0x", w, "\n");
/* and again in decimal format */
bdPrintDecimal("", u, " * ");
bdPrintDecimal("", v, " = ");
bdPrintDecimal("", w, "\n");
/* Free all objects we made */
bdFree(&u);
bdFree(&v);
bdFree(&w);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,77 +1,77 @@
/* $Id: t_mpJacobi.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#include <stdio.h>
#include <assert.h>
#include "bigdigits.h"
#define TEST_LEN (1024/8)
char *strA =
"6BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBAA9993E364706816ABA3E25717850"
"C26C9CD0D89D33CC";
const char *strN =
"CCD34C2F4D95FFAD1420E666C07E39D1450A1330"
"4C3F5891EDE57595C772A3691AB51D2BECE1476B"
"8F22AE223365F183BC3EE2D4CACDBA3AD0C4D478"
"1C523A10EFE6203D6F3BC226BF9A459727B8F122"
"C482D8C86019F9A869329187096430A6C67CB103"
"742BCBC66906AD23836EBABB511D5D80AB8CB599"
"74E9AAC62D785C45";
int main(void)
{
size_t ndigits = TEST_LEN;
DIGIT_T a[TEST_LEN];
DIGIT_T n[TEST_LEN];
int j;
/* Use example from X9.31 Appendix D.5.2 */
mpConvFromHex(a, ndigits, strA);
mpConvFromHex(n, ndigits, strN);
mpPrintHex("n=\n", n, ndigits, "\n");
mpPrintHex("a=\n", a, ndigits, "\n");
j= mpJacobi(a, n, ndigits);
printf("Jacobi(a/n)=%d\n", j);
assert(j == -1);
/* Divide a by 2 */
mpShiftRight(a, a, 1, ndigits);
mpPrintHex("a=a/2=\n", a, ndigits, "\n");
j= mpJacobi(a, n, ndigits);
printf("Jacobi(a/n)=%d\n", j);
assert(j == +1);
/* Make n|a */
mpShortMult(a, n, 7, ndigits);
mpPrintHex("a=n*7=\n", a, ndigits, "\n");
j= mpJacobi(a, n, ndigits);
printf("Jacobi(a/n)=%d\n", j);
assert(j == 0);
printf("Jacobi tests completed OK\n");
return 0;
}
/* $Id: t_mpJacobi.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
#include <stdio.h>
#include <assert.h>
#include "bigdigits.h"
#define TEST_LEN (1024/8)
char *strA =
"6BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
"BBBBBBBBBBBAA9993E364706816ABA3E25717850"
"C26C9CD0D89D33CC";
const char *strN =
"CCD34C2F4D95FFAD1420E666C07E39D1450A1330"
"4C3F5891EDE57595C772A3691AB51D2BECE1476B"
"8F22AE223365F183BC3EE2D4CACDBA3AD0C4D478"
"1C523A10EFE6203D6F3BC226BF9A459727B8F122"
"C482D8C86019F9A869329187096430A6C67CB103"
"742BCBC66906AD23836EBABB511D5D80AB8CB599"
"74E9AAC62D785C45";
int main(void)
{
size_t ndigits = TEST_LEN;
DIGIT_T a[TEST_LEN];
DIGIT_T n[TEST_LEN];
int j;
/* Use example from X9.31 Appendix D.5.2 */
mpConvFromHex(a, ndigits, strA);
mpConvFromHex(n, ndigits, strN);
mpPrintHex("n=\n", n, ndigits, "\n");
mpPrintHex("a=\n", a, ndigits, "\n");
j= mpJacobi(a, n, ndigits);
printf("Jacobi(a/n)=%d\n", j);
assert(j == -1);
/* Divide a by 2 */
mpShiftRight(a, a, 1, ndigits);
mpPrintHex("a=a/2=\n", a, ndigits, "\n");
j= mpJacobi(a, n, ndigits);
printf("Jacobi(a/n)=%d\n", j);
assert(j == +1);
/* Make n|a */
mpShortMult(a, n, 7, ndigits);
mpPrintHex("a=n*7=\n", a, ndigits, "\n");
j= mpJacobi(a, n, ndigits);
printf("Jacobi(a/n)=%d\n", j);
assert(j == 0);
printf("Jacobi tests completed OK\n");
return 0;
}

View File

@ -1,260 +1,260 @@
/* $Id: t_mpModArith.c $ */
/* Some more tests of the BigDigits "mp" functions. */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stdio.h>
#include "bigdigits.h"
/** Hard-coded maximum number of bits we choose to handle */
#define EC_MAXBITS 640
/** Number of digits needed to represent an integer of EC_MAXBITS bits */
#define EC_NDIGITS (EC_MAXBITS/BITS_PER_DIGIT)
/** Unsigned integer of EC_MAXBITS bits */
typedef DIGIT_T EC_INT[EC_NDIGITS];
/* This module can be compiled with the global preprocessor definitions
MSVC: /D "NO_ALLOCS" /D "MAX_FIXED_BIT_LENGTH=640"
GCC: -D NO_ALLOCS -D MAX_FIXED_BIT_LENGTH=640
*/
/** Make a random number of up to `nbits` bits */
size_t make_random(EC_INT a, size_t nbits)
{
size_t n;
/* Half the time, pick a shorter bitlength at random from [6,nbits] */
if (spSimpleRand(0, 1)) {
n = (size_t)spSimpleRand(6, (DIGIT_T)nbits);
}
else {
n = nbits;
}
mpQuickRandBits(a, EC_NDIGITS, n);
return n;
}
int main(void)
{
/* Note the neat way to declare variables of EC_NDIGITS */
EC_INT u, v, w, m, p, x, y;
size_t nbits;
int r;
/* Force linker to include copyright notice in
executable object image
*/
copyright_notice();
printf("Testing BIGDIGITS 'mp' modular arithmetic functions.\n");
// First show it works for small numbers...
mpSetDigit(u, 17, EC_NDIGITS);
mpSetDigit(v, 13, EC_NDIGITS);
mpSetDigit(m, 25, EC_NDIGITS);
mpPrintDecimal("u=", u, EC_NDIGITS, ", ");
mpPrintDecimal("v=", v, EC_NDIGITS, ", ");
mpPrintDecimal("m=", m, EC_NDIGITS, "\n");
mpModAdd(w, u, v, m, EC_NDIGITS);
mpPrintDecimal("w=u+v(mod m)=", w, EC_NDIGITS, "\n");
/* Check that w == 5 */
assert(mpShortCmp(w, 5, EC_NDIGITS) == 0);
// Add assign w+=u [NB (w,w,u) not (w,u,w)]
mpModAdd(w, w, u, m, EC_NDIGITS);
mpPrintDecimal("w+=u(mod m)=", w, EC_NDIGITS, "\n");
// Subtract assign w-=u
mpModSub(w, w, u, m, EC_NDIGITS);
mpPrintDecimal("w-=u(mod m)=", w, EC_NDIGITS, "\n");
// Subtract modulo m
mpModSub(w, v, u, m, EC_NDIGITS);
mpPrintDecimal("w=v-u(mod m)=", w, EC_NDIGITS, "\n");
mpModSub(w, u, v, m, EC_NDIGITS);
mpPrintDecimal("w=u-v(mod m)=", w, EC_NDIGITS, "\n");
// Add then subtract modulo m
mpModAdd(w, u, v, m, EC_NDIGITS);
mpPrintDecimal("w=u+v(mod m)=", w, EC_NDIGITS, "\n");
/* y = w - v */
mpModSub(y, w, v, m, EC_NDIGITS);
mpPrintDecimal("y=w-v(mod m)=", y, EC_NDIGITS, "\n");
/* Check y == u */
printf("y == u => %s\n", (mpEqual(y, u, EC_NDIGITS) ? "OK" : "ERROR"));
assert(mpEqual(y, u, EC_NDIGITS));
printf("Select a 192-bit prime number...\n");
mpConvFromHex(p, EC_NDIGITS, "fffffffffffffffffffffffffffffffeffffffffffffffff");
mpPrintHex("p=0x", p, EC_NDIGITS, "\n");
mpPrintDecimal("p=", p, EC_NDIGITS, "\n");
r = mpIsPrime(p, EC_NDIGITS, 50);
printf("mpIsPrime(p)=%d\n", r);
assert(r != 0);
printf("Find the square root of a quadratic residue modulo p ...\n");
/* Pick a number, any number, less than p */
nbits = mpBitLength(p, EC_NDIGITS);
make_random(u, nbits - 1);
mpPrintDecimal("u=", u, EC_NDIGITS, "\n");
/* Square it modulo p => a quadratic residue modulo p */
mpModSquare(w, u, p, EC_NDIGITS);
mpPrintDecimal("w=u^2(mod p)=", w, EC_NDIGITS, "\n");
/* Check we have a quadratic residue */
r = mpJacobi(w, p, EC_NDIGITS);
printf("Legendre symbol (w|p)=%d (expected 1)\n", r);
assert(r == 1);
/* Compute one modular square root */
mpModSqrt(x, w, p, EC_NDIGITS);
mpPrintDecimal("x=sqrt(w)(mod p)=", x, EC_NDIGITS, "\n");
/* and the other */
mpSubtract(y, p, x, EC_NDIGITS);
mpPrintDecimal("y=p-x=", y, EC_NDIGITS, "\n");
/* One of x or y is the same as u */
assert(mpEqual(x, u, EC_NDIGITS) || mpEqual(y, u, EC_NDIGITS));
if (mpEqual(x, u, EC_NDIGITS)) {
printf("u == x\n");
}
else {
printf("u == p-x\n");
}
printf("Find a number that is not a quadratic residue mod p...\n");
do {
make_random(v, nbits);
} while (mpJacobi(v, p, EC_NDIGITS) != -1);
mpPrintDecimal("v=", v, EC_NDIGITS, "\n");
printf("Legendre symbol (v|p)=%d (expected -1)\n", mpJacobi(v, p, EC_NDIGITS));
r = mpModSqrt(x, v, p, EC_NDIGITS);
printf("mpModSqrt(v) returns %d (-1 => square root does not exist)\n", r);
assert(r != 0);
printf("\nAdd and subtract modulo p...\n");
/* Add two random numbers w = u + v (mod p) */
make_random(u, nbits - 1);
make_random(v, nbits - 1);
mpPrintDecimal("u=", u, EC_NDIGITS, "\n");
mpPrintDecimal("v=", v, EC_NDIGITS, "\n");
mpModAdd(w, u, v, p, EC_NDIGITS);
mpPrintDecimal("w=u+v(mod p)=", w, EC_NDIGITS, "\n");
/* y = w - v (mod p) */
mpModSub(y, w, v, p, EC_NDIGITS);
mpPrintDecimal("y=w-v(mod p)=", y, EC_NDIGITS, "\n");
/* Check y == u */
printf("y == u => %s\n", (mpEqual(y, u, EC_NDIGITS) ? "OK" : "ERROR"));
assert(mpEqual(y, u, EC_NDIGITS));
printf("Do 'add assign' and 'subtract assign'...\n");
mpSetEqual(w, u, EC_NDIGITS);
mpPrintDecimal("y= ", w, EC_NDIGITS, "\n");
mpPrintDecimal("w=y= ", w, EC_NDIGITS, "\n");
mpPrintDecimal("v= ", v, EC_NDIGITS, "\n");
/* Now "add assign" w += v (mod p) */
mpModAdd(w, w, v, p, EC_NDIGITS);
mpPrintDecimal("w+=v(mod p)=", w, EC_NDIGITS, "\n");
/* and "subtract assign" w -= v (mod p) */
mpModSub(w, w, v, p, EC_NDIGITS);
mpPrintDecimal("w-=v(mod p)=", w, EC_NDIGITS, "\n");
/* Check w == y */
printf("w == y => %s\n", (mpEqual(w, y, EC_NDIGITS) ? "OK" : "ERROR"));
assert(mpEqual(w, y, EC_NDIGITS));
printf("\nDivide an integer by 2 modulo p - quick method...\n");
mpPrintDecimal("u= ", u, EC_NDIGITS, "\n");
mpModHalve(w, u, p, EC_NDIGITS);
mpPrintDecimal("w=u/2(mod p)=", w, EC_NDIGITS, "\n");
// Check result
mpModAdd(v, w, w, p, EC_NDIGITS);
mpPrintDecimal("v=w*2(mod p)=", v, EC_NDIGITS, "\n");
printf("v == u => %s\n", (mpEqual(v, u, EC_NDIGITS) ? "OK" : "ERROR"));
assert(mpEqual(v, u, EC_NDIGITS));
/* DEMONSTRATE "QUICK" MODULO REDUCTION FOR SPECIAL CASE */
printf("\nSpecial case modulo reduction...\n");
/* Compute v = u mod p for u in range 0 <= u < 4p */
mpPrintHex("p=", p, EC_NDIGITS, "\n");
nbits = mpBitLength(p, EC_NDIGITS);
printf("p is %d bits\n", nbits);
// Generate a random number approx 2-4x bigger than p
mpQuickRandBits(u, EC_NDIGITS, nbits + 2);
mpPrintHex("u=", u, EC_NDIGITS, "\n");
printf("u is %d bits\n", mpBitLength(u, EC_NDIGITS));
// Compute v = u mod p for this special case
mpModSpecial(v, u, p, EC_NDIGITS);
mpPrintHex("v=u(mod p)=", v, EC_NDIGITS, "\n");
// Check that result v < p
assert(mpCompare(v, p, EC_NDIGITS) < 0);
// And check again using the more expensive mpModulo fn
mpModulo(w, u, EC_NDIGITS, p, EC_NDIGITS);
mpPrintHex("mpModulo()=", w, EC_NDIGITS, "\n");
assert(mpEqual(v, w, EC_NDIGITS));
printf("\nDemonstrate mpPrintBits():\n");
mpSetDigit(u, 0xef, EC_NDIGITS);
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("'", u, EC_NDIGITS, "'b\n");
mpSetDigit(u, 0x28, EC_NDIGITS);
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("'", u, EC_NDIGITS, "'b\n");
mpSetDigit(u, 0, EC_NDIGITS);
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("'", u, EC_NDIGITS, "'b\n");
mpSetDigit(u, 0xdeadbeef, EC_NDIGITS);
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("'", u, EC_NDIGITS, "'b\n");
printf("(correct)= %s\n", "11011110101011011011111011101111");
mpConvFromHex(u, EC_NDIGITS, "04deadbeefcafebabe1");
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("\n'", u, EC_NDIGITS, "'b\n");
mpPrintHex("p=0x", p, EC_NDIGITS, " => ");
mpPrintBits("\n'", p, EC_NDIGITS, "'b\n");
/* Display version number */
printf("\nVERSION=%d\n", mpVersion());
printf("Compiled on [%s]\n", mpCompileTime());
printf("OK, successfully completed tests.\n");
return 0;
}
/* $Id: t_mpModArith.c $ */
/* Some more tests of the BigDigits "mp" functions. */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stdio.h>
#include "bigdigits.h"
/** Hard-coded maximum number of bits we choose to handle */
#define EC_MAXBITS 640
/** Number of digits needed to represent an integer of EC_MAXBITS bits */
#define EC_NDIGITS (EC_MAXBITS/BITS_PER_DIGIT)
/** Unsigned integer of EC_MAXBITS bits */
typedef DIGIT_T EC_INT[EC_NDIGITS];
/* This module can be compiled with the global preprocessor definitions
MSVC: /D "NO_ALLOCS" /D "MAX_FIXED_BIT_LENGTH=640"
GCC: -D NO_ALLOCS -D MAX_FIXED_BIT_LENGTH=640
*/
/** Make a random number of up to `nbits` bits */
size_t make_random(EC_INT a, size_t nbits)
{
size_t n;
/* Half the time, pick a shorter bitlength at random from [6,nbits] */
if (spSimpleRand(0, 1)) {
n = (size_t)spSimpleRand(6, (DIGIT_T)nbits);
}
else {
n = nbits;
}
mpQuickRandBits(a, EC_NDIGITS, n);
return n;
}
int main(void)
{
/* Note the neat way to declare variables of EC_NDIGITS */
EC_INT u, v, w, m, p, x, y;
size_t nbits;
int r;
/* Force linker to include copyright notice in
executable object image
*/
copyright_notice();
printf("Testing BIGDIGITS 'mp' modular arithmetic functions.\n");
// First show it works for small numbers...
mpSetDigit(u, 17, EC_NDIGITS);
mpSetDigit(v, 13, EC_NDIGITS);
mpSetDigit(m, 25, EC_NDIGITS);
mpPrintDecimal("u=", u, EC_NDIGITS, ", ");
mpPrintDecimal("v=", v, EC_NDIGITS, ", ");
mpPrintDecimal("m=", m, EC_NDIGITS, "\n");
mpModAdd(w, u, v, m, EC_NDIGITS);
mpPrintDecimal("w=u+v(mod m)=", w, EC_NDIGITS, "\n");
/* Check that w == 5 */
assert(mpShortCmp(w, 5, EC_NDIGITS) == 0);
// Add assign w+=u [NB (w,w,u) not (w,u,w)]
mpModAdd(w, w, u, m, EC_NDIGITS);
mpPrintDecimal("w+=u(mod m)=", w, EC_NDIGITS, "\n");
// Subtract assign w-=u
mpModSub(w, w, u, m, EC_NDIGITS);
mpPrintDecimal("w-=u(mod m)=", w, EC_NDIGITS, "\n");
// Subtract modulo m
mpModSub(w, v, u, m, EC_NDIGITS);
mpPrintDecimal("w=v-u(mod m)=", w, EC_NDIGITS, "\n");
mpModSub(w, u, v, m, EC_NDIGITS);
mpPrintDecimal("w=u-v(mod m)=", w, EC_NDIGITS, "\n");
// Add then subtract modulo m
mpModAdd(w, u, v, m, EC_NDIGITS);
mpPrintDecimal("w=u+v(mod m)=", w, EC_NDIGITS, "\n");
/* y = w - v */
mpModSub(y, w, v, m, EC_NDIGITS);
mpPrintDecimal("y=w-v(mod m)=", y, EC_NDIGITS, "\n");
/* Check y == u */
printf("y == u => %s\n", (mpEqual(y, u, EC_NDIGITS) ? "OK" : "ERROR"));
assert(mpEqual(y, u, EC_NDIGITS));
printf("Select a 192-bit prime number...\n");
mpConvFromHex(p, EC_NDIGITS, "fffffffffffffffffffffffffffffffeffffffffffffffff");
mpPrintHex("p=0x", p, EC_NDIGITS, "\n");
mpPrintDecimal("p=", p, EC_NDIGITS, "\n");
r = mpIsPrime(p, EC_NDIGITS, 50);
printf("mpIsPrime(p)=%d\n", r);
assert(r != 0);
printf("Find the square root of a quadratic residue modulo p ...\n");
/* Pick a number, any number, less than p */
nbits = mpBitLength(p, EC_NDIGITS);
make_random(u, nbits - 1);
mpPrintDecimal("u=", u, EC_NDIGITS, "\n");
/* Square it modulo p => a quadratic residue modulo p */
mpModSquare(w, u, p, EC_NDIGITS);
mpPrintDecimal("w=u^2(mod p)=", w, EC_NDIGITS, "\n");
/* Check we have a quadratic residue */
r = mpJacobi(w, p, EC_NDIGITS);
printf("Legendre symbol (w|p)=%d (expected 1)\n", r);
assert(r == 1);
/* Compute one modular square root */
mpModSqrt(x, w, p, EC_NDIGITS);
mpPrintDecimal("x=sqrt(w)(mod p)=", x, EC_NDIGITS, "\n");
/* and the other */
mpSubtract(y, p, x, EC_NDIGITS);
mpPrintDecimal("y=p-x=", y, EC_NDIGITS, "\n");
/* One of x or y is the same as u */
assert(mpEqual(x, u, EC_NDIGITS) || mpEqual(y, u, EC_NDIGITS));
if (mpEqual(x, u, EC_NDIGITS)) {
printf("u == x\n");
}
else {
printf("u == p-x\n");
}
printf("Find a number that is not a quadratic residue mod p...\n");
do {
make_random(v, nbits);
} while (mpJacobi(v, p, EC_NDIGITS) != -1);
mpPrintDecimal("v=", v, EC_NDIGITS, "\n");
printf("Legendre symbol (v|p)=%d (expected -1)\n", mpJacobi(v, p, EC_NDIGITS));
r = mpModSqrt(x, v, p, EC_NDIGITS);
printf("mpModSqrt(v) returns %d (-1 => square root does not exist)\n", r);
assert(r != 0);
printf("\nAdd and subtract modulo p...\n");
/* Add two random numbers w = u + v (mod p) */
make_random(u, nbits - 1);
make_random(v, nbits - 1);
mpPrintDecimal("u=", u, EC_NDIGITS, "\n");
mpPrintDecimal("v=", v, EC_NDIGITS, "\n");
mpModAdd(w, u, v, p, EC_NDIGITS);
mpPrintDecimal("w=u+v(mod p)=", w, EC_NDIGITS, "\n");
/* y = w - v (mod p) */
mpModSub(y, w, v, p, EC_NDIGITS);
mpPrintDecimal("y=w-v(mod p)=", y, EC_NDIGITS, "\n");
/* Check y == u */
printf("y == u => %s\n", (mpEqual(y, u, EC_NDIGITS) ? "OK" : "ERROR"));
assert(mpEqual(y, u, EC_NDIGITS));
printf("Do 'add assign' and 'subtract assign'...\n");
mpSetEqual(w, u, EC_NDIGITS);
mpPrintDecimal("y= ", w, EC_NDIGITS, "\n");
mpPrintDecimal("w=y= ", w, EC_NDIGITS, "\n");
mpPrintDecimal("v= ", v, EC_NDIGITS, "\n");
/* Now "add assign" w += v (mod p) */
mpModAdd(w, w, v, p, EC_NDIGITS);
mpPrintDecimal("w+=v(mod p)=", w, EC_NDIGITS, "\n");
/* and "subtract assign" w -= v (mod p) */
mpModSub(w, w, v, p, EC_NDIGITS);
mpPrintDecimal("w-=v(mod p)=", w, EC_NDIGITS, "\n");
/* Check w == y */
printf("w == y => %s\n", (mpEqual(w, y, EC_NDIGITS) ? "OK" : "ERROR"));
assert(mpEqual(w, y, EC_NDIGITS));
printf("\nDivide an integer by 2 modulo p - quick method...\n");
mpPrintDecimal("u= ", u, EC_NDIGITS, "\n");
mpModHalve(w, u, p, EC_NDIGITS);
mpPrintDecimal("w=u/2(mod p)=", w, EC_NDIGITS, "\n");
// Check result
mpModAdd(v, w, w, p, EC_NDIGITS);
mpPrintDecimal("v=w*2(mod p)=", v, EC_NDIGITS, "\n");
printf("v == u => %s\n", (mpEqual(v, u, EC_NDIGITS) ? "OK" : "ERROR"));
assert(mpEqual(v, u, EC_NDIGITS));
/* DEMONSTRATE "QUICK" MODULO REDUCTION FOR SPECIAL CASE */
printf("\nSpecial case modulo reduction...\n");
/* Compute v = u mod p for u in range 0 <= u < 4p */
mpPrintHex("p=", p, EC_NDIGITS, "\n");
nbits = mpBitLength(p, EC_NDIGITS);
printf("p is %d bits\n", nbits);
// Generate a random number approx 2-4x bigger than p
mpQuickRandBits(u, EC_NDIGITS, nbits + 2);
mpPrintHex("u=", u, EC_NDIGITS, "\n");
printf("u is %d bits\n", mpBitLength(u, EC_NDIGITS));
// Compute v = u mod p for this special case
mpModSpecial(v, u, p, EC_NDIGITS);
mpPrintHex("v=u(mod p)=", v, EC_NDIGITS, "\n");
// Check that result v < p
assert(mpCompare(v, p, EC_NDIGITS) < 0);
// And check again using the more expensive mpModulo fn
mpModulo(w, u, EC_NDIGITS, p, EC_NDIGITS);
mpPrintHex("mpModulo()=", w, EC_NDIGITS, "\n");
assert(mpEqual(v, w, EC_NDIGITS));
printf("\nDemonstrate mpPrintBits():\n");
mpSetDigit(u, 0xef, EC_NDIGITS);
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("'", u, EC_NDIGITS, "'b\n");
mpSetDigit(u, 0x28, EC_NDIGITS);
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("'", u, EC_NDIGITS, "'b\n");
mpSetDigit(u, 0, EC_NDIGITS);
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("'", u, EC_NDIGITS, "'b\n");
mpSetDigit(u, 0xdeadbeef, EC_NDIGITS);
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("'", u, EC_NDIGITS, "'b\n");
printf("(correct)= %s\n", "11011110101011011011111011101111");
mpConvFromHex(u, EC_NDIGITS, "04deadbeefcafebabe1");
mpPrintHex("u=0x", u, EC_NDIGITS, " => ");
mpPrintBits("\n'", u, EC_NDIGITS, "'b\n");
mpPrintHex("p=0x", p, EC_NDIGITS, " => ");
mpPrintBits("\n'", p, EC_NDIGITS, "'b\n");
/* Display version number */
printf("\nVERSION=%d\n", mpVersion());
printf("Compiled on [%s]\n", mpCompileTime());
printf("OK, successfully completed tests.\n");
return 0;
}

View File

@ -1,226 +1,226 @@
/* $Id: t_mpRSA508.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* Test vector using BIGDIGITS to show RSA digital signature using 508-bit test vectors from
"Some Examples of the PKCS Standards"
An RSA Laboratories Technical Note
Burton S. Kaliski Jr.
Revised November 1, 1993
*/
/* ---
From the document:-
In the example, the modulus n is the following 508-bit
integer:
n = 0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0 c0 01 c6
27 10 27 00 75 14 29 42 e1 9a 8d 8c 51 d0 53 b3 e3 78 2a 1d
e5 dc 5a f4 eb e9 94 68 17 01 14 a1 df e6 7c dc 9a 9a f5 5d
65 56 20 bb ab
The public exponent e is F4 (65537):
e = 01 00 01
The private exponent d:
d = 01 23 c5 b6 1b a3 6e db 1d 36 79 90 41 99 a8 9e a8 0c 09
b9 12 2e 14 00 c0 9a dc f7 78 46 76 d0 1d 23 35 6a 7d 44 d6
bd 8b d5 0e 94 bf c7 23 fa 87 d8 86 2b 75 17 76 91 c1 1d 75
76 92 df 88 81
RSA signing according to PKCS #1 has two general steps:
An encryption block is constructed from a block type, a
padding string, and the prefixed message digest; then the
encryption block is exponentiated with Test User 1's private
exponent.
The encryption block EB is the following 64-octet string:
00
01 block type
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff padding string
ff ff ff ff ff ff ff ff ff ff ff
00 00 separator
30 20
30 0c digestAlgorithm
06 08 2a 86 48 86 f7 0d 02 02 algorithm = md2
05 00 parameters = NULL
04 10 digest
dc a9 ec f1 c1 5c 1b d2 66 af f9 c8 79 93 65 cd
i.e. the 64-octet string:
00 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff 00 30 20
30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04 10
dc a9 ec f1 c1 5c 1b d2 66 af f9 c8 79 93 65 cd
The resulting encrypted message digest (the signature) is
the following 64-octet string:
06 db 36 cb 18 d3 47 5b 9c 01 db 3c 78 95 28 08
02 79 bb ae ff 2b 7d 55 8e d6 61 59 87 c8 51 86
3f 8a 6c 2c ff bc 89 c3 f7 5a 18 d9 6b 12 7c 71
7d 54 d0 d8 04 8d a8 a0 54 46 26 d1 7a 2a 8f be
CAUTION: Note that this example is for a digital signature, not encryption
to keep a secret. To use RSA to encrypt a message, you should use *random*
padding in the encryption block, different each time, not the fixed block
of FF padding bytes used here, and you exponentiate with the recipient's
*public* exponent. The recipient then deciphers using his private exponent.
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "bigdigits.h"
#define MOD_SIZE 16 /* max 512-bits */
void pr_bytes(unsigned char *b, size_t nbytes)
{
size_t i;
for (i = 0; i < nbytes; i++)
{
if (i && (i % 16 == 0)) printf("\n");
printf("%02x ", b[i]);
}
printf("\n");
}
int main(void)
{
DIGIT_T n[MOD_SIZE], e[MOD_SIZE], d[MOD_SIZE];
DIGIT_T s[MOD_SIZE], m[MOD_SIZE], m1[MOD_SIZE], s1[MOD_SIZE];
size_t nbytes;
char decimal[MOD_SIZE*4];
/* Data in big-endian byte format:-
*/
unsigned char nn[] = {
0x0A, 0x66, 0x79, 0x1D, 0xC6, 0x98, 0x81, 0x68,
0xDE, 0x7A, 0xB7, 0x74, 0x19, 0xBB, 0x7F, 0xB0,
0xC0, 0x01, 0xC6, 0x27, 0x10, 0x27, 0x00, 0x75,
0x14, 0x29, 0x42, 0xE1, 0x9A, 0x8D, 0x8C, 0x51,
0xD0, 0x53, 0xB3, 0xE3, 0x78, 0x2A, 0x1D, 0xE5,
0xDC, 0x5A, 0xF4, 0xEB, 0xE9, 0x94, 0x68, 0x17,
0x01, 0x14, 0xA1, 0xDF, 0xE6, 0x7C, 0xDC, 0x9A,
0x9A, 0xF5, 0x5D, 0x65, 0x56, 0x20, 0xBB, 0xAB,
};
unsigned char ee[] = { 0x01, 0x00, 0x01 };
unsigned char dd[] = {
0x01, 0x23, 0xC5, 0xB6, 0x1B, 0xA3, 0x6E, 0xDB,
0x1D, 0x36, 0x79, 0x90, 0x41, 0x99, 0xA8, 0x9E,
0xA8, 0x0C, 0x09, 0xB9, 0x12, 0x2E, 0x14, 0x00,
0xC0, 0x9A, 0xDC, 0xF7, 0x78, 0x46, 0x76, 0xD0,
0x1D, 0x23, 0x35, 0x6A, 0x7D, 0x44, 0xD6, 0xBD,
0x8B, 0xD5, 0x0E, 0x94, 0xBF, 0xC7, 0x23, 0xFA,
0x87, 0xD8, 0x86, 0x2B, 0x75, 0x17, 0x76, 0x91,
0xC1, 0x1D, 0x75, 0x76, 0x92, 0xDF, 0x88, 0x81,
};
unsigned char mm[] = {
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x30, 0x20,
0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10,
0xDC, 0xA9, 0xEC, 0xF1, 0xC1, 0x5C, 0x1B, 0xD2,
0x66, 0xAF, 0xF9, 0xC8, 0x79, 0x93, 0x65, 0xCD,
};
unsigned char ss[] = {
0x06, 0xDB, 0x36, 0xCB, 0x18, 0xD3, 0x47, 0x5B,
0x9C, 0x01, 0xDB, 0x3C, 0x78, 0x95, 0x28, 0x08,
0x02, 0x79, 0xBB, 0xAE, 0xFF, 0x2B, 0x7D, 0x55,
0x8E, 0xD6, 0x61, 0x59, 0x87, 0xC8, 0x51, 0x86,
0x3F, 0x8A, 0x6C, 0x2C, 0xFF, 0xBC, 0x89, 0xC3,
0xF7, 0x5A, 0x18, 0xD9, 0x6B, 0x12, 0x7C, 0x71,
0x7D, 0x54, 0xD0, 0xD8, 0x04, 0x8D, 0xA8, 0xA0,
0x54, 0x46, 0x26, 0xD1, 0x7A, 0x2A, 0x8F, 0xBE,
};
printf("Test BIGDIGITS using 508-bit RSA key from 'Some Examples of the PKCS Standards'\n");
/* Convert bytes to BIGDIGITS */
mpConvFromOctets(n, MOD_SIZE, nn, sizeof(nn));
mpConvFromOctets(e, MOD_SIZE, ee, sizeof(ee));
mpConvFromOctets(d, MOD_SIZE, dd, sizeof(dd));
mpConvFromOctets(m, MOD_SIZE, mm, sizeof(mm));
mpConvFromOctets(s1, MOD_SIZE, ss, sizeof(ss));
mpPrintHex("n =", n, MOD_SIZE, "\n");
mpPrintHex("e =", e, MOD_SIZE, "\n");
mpPrintHex("d =", d, MOD_SIZE, "\n");
mpPrintHex("m =", m, MOD_SIZE, "\n");
/* Sign, i.e. Encrypt with private key, s = m^d mod n */
mpModExp(s, m, d, n, MOD_SIZE);
mpPrintHex("s =", s, MOD_SIZE, " ");
/* Did we get the same answer as expected? */
if (!mpEqual(s1, s, MOD_SIZE))
printf("<= ERROR - no match\n");
else
printf("<= OK\n");
assert(mpEqual(s1, s, MOD_SIZE));
/* Verify, i.e. Decrypt with public key m' = s^e mod n */
mpModExp(m1, s, e, n, MOD_SIZE);
mpPrintHex("m'=", m1, MOD_SIZE, " ");
/* Check that we got back where we started */
if (!mpEqual(m1, m, MOD_SIZE))
printf("<= ERROR - no match\n");
else
printf("<= OK\n");
assert(mpEqual(m1, m, MOD_SIZE));
/* Now convert back to octets (bytes) */
printf("Convert BIGDIGITS back to octets (bytes)...\n");
memset(mm, 0, sizeof(mm));
nbytes = mpConvToOctets(m, MOD_SIZE, mm, sizeof(mm));
printf("%d non-zero bytes converted from m:\n", nbytes);
pr_bytes(mm, sizeof(mm));
memset(ee, 0, sizeof(ee));
nbytes = mpConvToOctets(e, MOD_SIZE, ee, sizeof(ee));
printf("%d non-zero bytes converted from e:\n", nbytes);
pr_bytes(ee, sizeof(ee));
/* Do a conversion to decimal */
nbytes = mpConvToDecimal(e, MOD_SIZE, decimal, sizeof(decimal));
printf("%d non-zero decimal digits converted from e:\n", nbytes);
printf("%s\n", decimal);
assert(strcmp(decimal, "65537") == 0);
printf("OK, successfully completed tests.\n");
return 0;
}
/* $Id: t_mpRSA508.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* Test vector using BIGDIGITS to show RSA digital signature using 508-bit test vectors from
"Some Examples of the PKCS Standards"
An RSA Laboratories Technical Note
Burton S. Kaliski Jr.
Revised November 1, 1993
*/
/* ---
From the document:-
In the example, the modulus n is the following 508-bit
integer:
n = 0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0 c0 01 c6
27 10 27 00 75 14 29 42 e1 9a 8d 8c 51 d0 53 b3 e3 78 2a 1d
e5 dc 5a f4 eb e9 94 68 17 01 14 a1 df e6 7c dc 9a 9a f5 5d
65 56 20 bb ab
The public exponent e is F4 (65537):
e = 01 00 01
The private exponent d:
d = 01 23 c5 b6 1b a3 6e db 1d 36 79 90 41 99 a8 9e a8 0c 09
b9 12 2e 14 00 c0 9a dc f7 78 46 76 d0 1d 23 35 6a 7d 44 d6
bd 8b d5 0e 94 bf c7 23 fa 87 d8 86 2b 75 17 76 91 c1 1d 75
76 92 df 88 81
RSA signing according to PKCS #1 has two general steps:
An encryption block is constructed from a block type, a
padding string, and the prefixed message digest; then the
encryption block is exponentiated with Test User 1's private
exponent.
The encryption block EB is the following 64-octet string:
00
01 block type
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff padding string
ff ff ff ff ff ff ff ff ff ff ff
00 00 separator
30 20
30 0c digestAlgorithm
06 08 2a 86 48 86 f7 0d 02 02 algorithm = md2
05 00 parameters = NULL
04 10 digest
dc a9 ec f1 c1 5c 1b d2 66 af f9 c8 79 93 65 cd
i.e. the 64-octet string:
00 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff 00 30 20
30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04 10
dc a9 ec f1 c1 5c 1b d2 66 af f9 c8 79 93 65 cd
The resulting encrypted message digest (the signature) is
the following 64-octet string:
06 db 36 cb 18 d3 47 5b 9c 01 db 3c 78 95 28 08
02 79 bb ae ff 2b 7d 55 8e d6 61 59 87 c8 51 86
3f 8a 6c 2c ff bc 89 c3 f7 5a 18 d9 6b 12 7c 71
7d 54 d0 d8 04 8d a8 a0 54 46 26 d1 7a 2a 8f be
CAUTION: Note that this example is for a digital signature, not encryption
to keep a secret. To use RSA to encrypt a message, you should use *random*
padding in the encryption block, different each time, not the fixed block
of FF padding bytes used here, and you exponentiate with the recipient's
*public* exponent. The recipient then deciphers using his private exponent.
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "bigdigits.h"
#define MOD_SIZE 16 /* max 512-bits */
void pr_bytes(unsigned char *b, size_t nbytes)
{
size_t i;
for (i = 0; i < nbytes; i++)
{
if (i && (i % 16 == 0)) printf("\n");
printf("%02x ", b[i]);
}
printf("\n");
}
int main(void)
{
DIGIT_T n[MOD_SIZE], e[MOD_SIZE], d[MOD_SIZE];
DIGIT_T s[MOD_SIZE], m[MOD_SIZE], m1[MOD_SIZE], s1[MOD_SIZE];
size_t nbytes;
char decimal[MOD_SIZE*4];
/* Data in big-endian byte format:-
*/
unsigned char nn[] = {
0x0A, 0x66, 0x79, 0x1D, 0xC6, 0x98, 0x81, 0x68,
0xDE, 0x7A, 0xB7, 0x74, 0x19, 0xBB, 0x7F, 0xB0,
0xC0, 0x01, 0xC6, 0x27, 0x10, 0x27, 0x00, 0x75,
0x14, 0x29, 0x42, 0xE1, 0x9A, 0x8D, 0x8C, 0x51,
0xD0, 0x53, 0xB3, 0xE3, 0x78, 0x2A, 0x1D, 0xE5,
0xDC, 0x5A, 0xF4, 0xEB, 0xE9, 0x94, 0x68, 0x17,
0x01, 0x14, 0xA1, 0xDF, 0xE6, 0x7C, 0xDC, 0x9A,
0x9A, 0xF5, 0x5D, 0x65, 0x56, 0x20, 0xBB, 0xAB,
};
unsigned char ee[] = { 0x01, 0x00, 0x01 };
unsigned char dd[] = {
0x01, 0x23, 0xC5, 0xB6, 0x1B, 0xA3, 0x6E, 0xDB,
0x1D, 0x36, 0x79, 0x90, 0x41, 0x99, 0xA8, 0x9E,
0xA8, 0x0C, 0x09, 0xB9, 0x12, 0x2E, 0x14, 0x00,
0xC0, 0x9A, 0xDC, 0xF7, 0x78, 0x46, 0x76, 0xD0,
0x1D, 0x23, 0x35, 0x6A, 0x7D, 0x44, 0xD6, 0xBD,
0x8B, 0xD5, 0x0E, 0x94, 0xBF, 0xC7, 0x23, 0xFA,
0x87, 0xD8, 0x86, 0x2B, 0x75, 0x17, 0x76, 0x91,
0xC1, 0x1D, 0x75, 0x76, 0x92, 0xDF, 0x88, 0x81,
};
unsigned char mm[] = {
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x30, 0x20,
0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10,
0xDC, 0xA9, 0xEC, 0xF1, 0xC1, 0x5C, 0x1B, 0xD2,
0x66, 0xAF, 0xF9, 0xC8, 0x79, 0x93, 0x65, 0xCD,
};
unsigned char ss[] = {
0x06, 0xDB, 0x36, 0xCB, 0x18, 0xD3, 0x47, 0x5B,
0x9C, 0x01, 0xDB, 0x3C, 0x78, 0x95, 0x28, 0x08,
0x02, 0x79, 0xBB, 0xAE, 0xFF, 0x2B, 0x7D, 0x55,
0x8E, 0xD6, 0x61, 0x59, 0x87, 0xC8, 0x51, 0x86,
0x3F, 0x8A, 0x6C, 0x2C, 0xFF, 0xBC, 0x89, 0xC3,
0xF7, 0x5A, 0x18, 0xD9, 0x6B, 0x12, 0x7C, 0x71,
0x7D, 0x54, 0xD0, 0xD8, 0x04, 0x8D, 0xA8, 0xA0,
0x54, 0x46, 0x26, 0xD1, 0x7A, 0x2A, 0x8F, 0xBE,
};
printf("Test BIGDIGITS using 508-bit RSA key from 'Some Examples of the PKCS Standards'\n");
/* Convert bytes to BIGDIGITS */
mpConvFromOctets(n, MOD_SIZE, nn, sizeof(nn));
mpConvFromOctets(e, MOD_SIZE, ee, sizeof(ee));
mpConvFromOctets(d, MOD_SIZE, dd, sizeof(dd));
mpConvFromOctets(m, MOD_SIZE, mm, sizeof(mm));
mpConvFromOctets(s1, MOD_SIZE, ss, sizeof(ss));
mpPrintHex("n =", n, MOD_SIZE, "\n");
mpPrintHex("e =", e, MOD_SIZE, "\n");
mpPrintHex("d =", d, MOD_SIZE, "\n");
mpPrintHex("m =", m, MOD_SIZE, "\n");
/* Sign, i.e. Encrypt with private key, s = m^d mod n */
mpModExp(s, m, d, n, MOD_SIZE);
mpPrintHex("s =", s, MOD_SIZE, " ");
/* Did we get the same answer as expected? */
if (!mpEqual(s1, s, MOD_SIZE))
printf("<= ERROR - no match\n");
else
printf("<= OK\n");
assert(mpEqual(s1, s, MOD_SIZE));
/* Verify, i.e. Decrypt with public key m' = s^e mod n */
mpModExp(m1, s, e, n, MOD_SIZE);
mpPrintHex("m'=", m1, MOD_SIZE, " ");
/* Check that we got back where we started */
if (!mpEqual(m1, m, MOD_SIZE))
printf("<= ERROR - no match\n");
else
printf("<= OK\n");
assert(mpEqual(m1, m, MOD_SIZE));
/* Now convert back to octets (bytes) */
printf("Convert BIGDIGITS back to octets (bytes)...\n");
memset(mm, 0, sizeof(mm));
nbytes = mpConvToOctets(m, MOD_SIZE, mm, sizeof(mm));
printf("%d non-zero bytes converted from m:\n", nbytes);
pr_bytes(mm, sizeof(mm));
memset(ee, 0, sizeof(ee));
nbytes = mpConvToOctets(e, MOD_SIZE, ee, sizeof(ee));
printf("%d non-zero bytes converted from e:\n", nbytes);
pr_bytes(ee, sizeof(ee));
/* Do a conversion to decimal */
nbytes = mpConvToDecimal(e, MOD_SIZE, decimal, sizeof(decimal));
printf("%d non-zero decimal digits converted from e:\n", nbytes);
printf("%s\n", decimal);
assert(strcmp(decimal, "65537") == 0);
printf("OK, successfully completed tests.\n");
return 0;
}

View File

@ -1,339 +1,339 @@
/* $Id: t_mpTest.c $ */
/* Some tests of the BigDigits "mp" functions. Not exhaustive. */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stdio.h>
#include "bigdigits.h"
#include "bigdigitsRand.h"
#define TEST_LEN 32
static int debug = 1;
DIGIT_T u[TEST_LEN];
DIGIT_T v[TEST_LEN];
DIGIT_T w[TEST_LEN];
DIGIT_T q[TEST_LEN];
DIGIT_T r[TEST_LEN];
DIGIT_T p1[TEST_LEN];
DIGIT_T p2[TEST_LEN];
DIGIT_T p3[TEST_LEN];
DIGIT_T g[TEST_LEN];
DIGIT_T a[TEST_LEN];
DIGIT_T n[TEST_LEN];
void ClearAll(void)
{
mpSetZero(u, TEST_LEN);
mpSetZero(v, TEST_LEN);
mpSetZero(w, TEST_LEN);
mpSetZero(q, TEST_LEN);
mpSetZero(r, TEST_LEN);
mpSetZero(g, TEST_LEN);
mpSetZero(p1, TEST_LEN);
mpSetZero(p2, TEST_LEN);
mpSetZero(p3, TEST_LEN);
mpSetZero(a, TEST_LEN);
mpSetZero(n, TEST_LEN);
}
static int MakeMultiplePrime(DIGIT_T p[], size_t ndigits)
{ /* Returns a random prime number of ndigits */
/* WARNING: This is not cryptographically secure
because the random number generator isn't */
size_t i;
for (i = 0; i < ndigits; i++)
p[i] = spBetterRand();
/* Make sure the highest and low bits are set */
p[ndigits - 1] |= HIBITMASK;
p[0] |= 0x1;
//printf("p="); mpPrintNL(p, ndigits);
/* Check if prime */
while (!mpIsPrime(p, ndigits, 10))
{
/* Keep adding 2 until find a prime */
mpShortAdd(p, p, 2, ndigits);
//printf("p="); mpPrintNL(p, ndigits);
printf(".");
/* Check for overflow */
if (!(p[ndigits - 1] & HIBITMASK))
return -1; /* Failed to find a prime */
}
return 0;
}
size_t MakeMultipleRandom(DIGIT_T a[], size_t ndigits)
{
/* Make a random number of up to ndigits digits */
size_t i, n, bits;
DIGIT_T mask;
n = (size_t)spSimpleRand(1, ndigits);
for (i = 0; i < n; i++)
a[i] = spBetterRand();
for (i = n; i < ndigits; i++)
a[i] = 0;
/* Zero out a random number of bits in leading digit
about half the time */
bits = (size_t)spSimpleRand(0, 2*BITS_PER_DIGIT);
if (bits != 0 && bits < BITS_PER_DIGIT)
{
mask = HIBITMASK;
for (i = 1; i < bits; i++)
{
mask |= (mask >> 1);
}
mask = ~mask;
a[n-1] &= mask;
}
return n;
}
void ShowAdd(DIGIT_T w[], DIGIT_T u[], DIGIT_T v[],
DIGIT_T carry, size_t ndigits)
{
mpPrintHex("mpAdd: ", u, ndigits, " + ");
mpPrintHex("", v, ndigits, " = ");
mpPrintHex("", w, ndigits, ", ");
printf("carry = %" PRIxBIGD "\n", carry);
}
void ShowMult(DIGIT_T w[], DIGIT_T u[], DIGIT_T v[], size_t ndigits)
{
mpPrintHex("mpMultiply: ", u, ndigits, " x ");
mpPrintHex("", v, ndigits, " = ");
mpPrintHex("", w, ndigits*2, "\n");
}
void ShowDiv(DIGIT_T q[], DIGIT_T r[], DIGIT_T u[], DIGIT_T v[], size_t ndigits)
{
mpPrintHex("mpDivide: ", u, ndigits, " / ");
mpPrintHex("", v, ndigits, " = ");
mpPrintHex("", q, ndigits, " ");
mpPrintHex("rem ", r, ndigits, "\n");
}
int main(void)
{
DIGIT_T carry, m;
int jac;
size_t len;
size_t NDIGITS;
/* Force linker to include copyright notice in
executable object image
*/
copyright_notice();
ClearAll();
printf("Testing BIGDIGITS 'mp' functions.\n");
/* Start easy: 1 + 1 = 2 */
mpSetDigit(u, 1, TEST_LEN); /* u = 1 */
carry = mpAdd(w, u, u, TEST_LEN); /* w = u + u */
ShowAdd(w, u, u, carry, TEST_LEN);
/* Check that w == 2 */
assert(mpShortCmp(w, 2, TEST_LEN) == 0);
/* ---- Add and subtract ---- */
/* Add two random numbers w = u + v */
MakeMultipleRandom(u, TEST_LEN-1);
MakeMultipleRandom(v, TEST_LEN-1);
carry = mpAdd(w, u, v, TEST_LEN);
/* r = w - v */
carry = mpSubtract(r, w, v, TEST_LEN);
/* Check r == u */
assert(mpEqual(r, u, TEST_LEN));
printf("Add and subtract worked OK\n");
ClearAll();
/* ---- Multiply and divide ---- */
/* Multiply two random numbers w = u * v */
MakeMultipleRandom(u, TEST_LEN / 2);
MakeMultipleRandom(v, TEST_LEN / 2);
mpMultiply(w, u, v, TEST_LEN / 2);
if (debug) ShowMult(w, u, v, TEST_LEN / 2);
/* q = w / v, r = w % v */
mpDivide(q, r, w, TEST_LEN, v, TEST_LEN / 2);
/* Check q == u and r == 0 */
if (debug) mpPrintHex("q=", q, TEST_LEN / 2, "\n");
assert(mpEqual(q, u, TEST_LEN / 2));
assert(mpIsZero(r, TEST_LEN / 2));
ClearAll();
mpSetDigit(a, 0, TEST_LEN);
mpSetZero(n, TEST_LEN);
assert(mpEqual(a, n, TEST_LEN));
ClearAll();
/* Pick two random numbers u, v */
MakeMultipleRandom(u, TEST_LEN/2);
MakeMultipleRandom(v, TEST_LEN/2);
/* Divide one by the other: q = u / v, r = u % v */
mpDivide(q, r, u, TEST_LEN/2, v, TEST_LEN/2);
if (debug) ShowDiv(q, r, u, v, TEST_LEN/2);
/* Check w = q * v + r == u */
mpMultiply(g, q, v, TEST_LEN/2);
mpAdd(w, g, r, TEST_LEN/2);
assert(mpEqual(w, u, TEST_LEN/2));
printf("Multiply and divide worked OK\n");
/* ---- Greatest Common Divisor ---- */
/* Pick 3x random primes p1, p2, p3 */
printf("Creating 3 prime numbers (be patient):\n");
MakeMultiplePrime(p1, TEST_LEN / 2);
printf("(1)\n");
MakeMultiplePrime(p2, TEST_LEN / 2);
printf("(2)\n");
MakeMultiplePrime(p3, TEST_LEN / 2);
printf("(3)\n");
/* Calculate two products from these primes */
/* u = p1 * p2 */
mpMultiply(u, p1, p2, TEST_LEN / 2);
/* v = p1 * p3 */
mpMultiply(v, p1, p3, TEST_LEN / 2);
/* Now calculate g = gcd(u, v) */
mpGcd(g, u, v, TEST_LEN);
/* And check that g == p1 */
assert(mpEqual(g, p1, TEST_LEN));
printf("Greatest Common Divisor worked OK\n");
/* ---- Modular Inverse ---- */
/* Use previous prime as modulus, v */
mpSetEqual(v, p1, TEST_LEN);
/* Pick a small multiplier, m */
m = spSimpleRand(1, MAX_DIGIT);
/* Set u = (vm - 1) */
mpShortMult(u, v, m, TEST_LEN);
mpShortSub(u, u, 1, TEST_LEN);
mpModInv(w, u, v, TEST_LEN);
/* Check that g = (w * u) mod v = 1 */
mpModMult(g, w, u, v, TEST_LEN);
assert((mpShortCmp(g, 1, TEST_LEN) == 0));
printf("Modular inverse worked OK\n");
/* Compute some Jacobi and Legendre symbol values */
mpSetDigit(a, 158, TEST_LEN);
mpSetDigit(n, 235, TEST_LEN);
jac = mpJacobi(a, n, TEST_LEN);
//printf("Jacobi(158, 235)=%d\n", jac);
assert(-1 == jac);
mpSetDigit(a, 2183, TEST_LEN);
mpSetDigit(n, 9907, TEST_LEN);
jac = mpJacobi(a, n, TEST_LEN);
//printf("Jacobi(2183, 9907)=%d\n", jac);
assert(1 == jac);
mpSetDigit(a, 1001, TEST_LEN);
jac = mpJacobi(a, n, TEST_LEN);
//printf("Jacobi(1001, 9907)=%d\n", jac);
assert(-1 == jac);
mpShortMult(a, n, 10000, TEST_LEN);
jac = mpJacobi(a, n, TEST_LEN);
//printf("Jacobi(10000 * 9907, 9907)=%d\n", jac);
assert(0 == jac);
printf("Jacobi symbol tests worked OK\n");
/* ---- Square, square root and cube root ---- */
printf("\nSquare roots, etc...\n");
/* Pick a random number u */
MakeMultipleRandom(u, TEST_LEN/2);
mpPrintHex("u=", u, TEST_LEN/2, "\n");
/* Compute square */
mpSquare(v, u, TEST_LEN/2);
mpPrintHex("u^2=", v, TEST_LEN, "\n");
/* Compute square root */
mpSqrt(r, v, TEST_LEN);
mpPrintHex("sqrt(u^2)=", r, TEST_LEN, "\n");
/* Now compute square root of v - 1 */
mpShortSub(v, v, 1, TEST_LEN);
mpSqrt(w, v, TEST_LEN);
mpPrintHex("sqrt(u^2-1)=", w, TEST_LEN, "\n");
/* This should be one less than before */
mpSubtract(g, r, w, TEST_LEN);
mpPrintHex("difference=", g, TEST_LEN, " (expecting 1)\n");
assert(mpShortCmp(g, 1, TEST_LEN) == 0);
/* Compute cube */
ClearAll();
/* Pick another random number u */
len = TEST_LEN/4;
MakeMultipleRandom(u, len);
mpPrintHex("u=", u, len, "\n");
/* Compute cube (NB we use LEN/4 to avoid overflow on 2nd multiplication) */
mpSquare(w, u, len);
len = 2 * len;
mpMultiply(v, w, u, len);
mpPrintHex("u^3=", v, TEST_LEN, "\n");
/* Compute cube root */
mpCubeRoot(r, v, TEST_LEN);
mpPrintHex("cuberoot(u^3)=", r, TEST_LEN, "\n");
assert(mpCompare(r, u, TEST_LEN) == 0);
/* Now compute cube root of v - 1 */
mpShortSub(v, v, 1, TEST_LEN);
mpCubeRoot(w, v, TEST_LEN);
mpPrintHex("cuberoot(u^3-1)=", w, TEST_LEN, "\n");
/* This should be one less than before */
mpSubtract(g, r, w, TEST_LEN);
mpPrintHex("difference=", g, TEST_LEN, " (expecting 1)\n");
assert(mpShortCmp(g, 1, TEST_LEN) == 0);
printf("Testing signed arithmetic...\n");
NDIGITS = 4;
mpSetDigit(u, 2, NDIGITS);
mpSetDigit(v, 5, NDIGITS);
mpSubtract(w, u, v, NDIGITS);
mpPrintDecimalSigned("signed w=", w, NDIGITS, "\n");
mpPrintHex("unsigned w=0x", w, NDIGITS, "\n");
/* Display version number */
printf("\nVersion=%d\n", mpVersion());
/* For further checks do RSA calculation - see t_mpRSA.c */
printf("OK, successfully completed tests.\n");
return 0;
}
/* $Id: t_mpTest.c $ */
/* Some tests of the BigDigits "mp" functions. Not exhaustive. */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2016-03-31 09:51:00 $
* $Revision: 2.6.1 $
* $Author: dai $
*/
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <stdio.h>
#include "bigdigits.h"
#include "bigdigitsRand.h"
#define TEST_LEN 32
static int debug = 1;
DIGIT_T u[TEST_LEN];
DIGIT_T v[TEST_LEN];
DIGIT_T w[TEST_LEN];
DIGIT_T q[TEST_LEN];
DIGIT_T r[TEST_LEN];
DIGIT_T p1[TEST_LEN];
DIGIT_T p2[TEST_LEN];
DIGIT_T p3[TEST_LEN];
DIGIT_T g[TEST_LEN];
DIGIT_T a[TEST_LEN];
DIGIT_T n[TEST_LEN];
void ClearAll(void)
{
mpSetZero(u, TEST_LEN);
mpSetZero(v, TEST_LEN);
mpSetZero(w, TEST_LEN);
mpSetZero(q, TEST_LEN);
mpSetZero(r, TEST_LEN);
mpSetZero(g, TEST_LEN);
mpSetZero(p1, TEST_LEN);
mpSetZero(p2, TEST_LEN);
mpSetZero(p3, TEST_LEN);
mpSetZero(a, TEST_LEN);
mpSetZero(n, TEST_LEN);
}
static int MakeMultiplePrime(DIGIT_T p[], size_t ndigits)
{ /* Returns a random prime number of ndigits */
/* WARNING: This is not cryptographically secure
because the random number generator isn't */
size_t i;
for (i = 0; i < ndigits; i++)
p[i] = spBetterRand();
/* Make sure the highest and low bits are set */
p[ndigits - 1] |= HIBITMASK;
p[0] |= 0x1;
//printf("p="); mpPrintNL(p, ndigits);
/* Check if prime */
while (!mpIsPrime(p, ndigits, 10))
{
/* Keep adding 2 until find a prime */
mpShortAdd(p, p, 2, ndigits);
//printf("p="); mpPrintNL(p, ndigits);
printf(".");
/* Check for overflow */
if (!(p[ndigits - 1] & HIBITMASK))
return -1; /* Failed to find a prime */
}
return 0;
}
size_t MakeMultipleRandom(DIGIT_T a[], size_t ndigits)
{
/* Make a random number of up to ndigits digits */
size_t i, n, bits;
DIGIT_T mask;
n = (size_t)spSimpleRand(1, ndigits);
for (i = 0; i < n; i++)
a[i] = spBetterRand();
for (i = n; i < ndigits; i++)
a[i] = 0;
/* Zero out a random number of bits in leading digit
about half the time */
bits = (size_t)spSimpleRand(0, 2*BITS_PER_DIGIT);
if (bits != 0 && bits < BITS_PER_DIGIT)
{
mask = HIBITMASK;
for (i = 1; i < bits; i++)
{
mask |= (mask >> 1);
}
mask = ~mask;
a[n-1] &= mask;
}
return n;
}
void ShowAdd(DIGIT_T w[], DIGIT_T u[], DIGIT_T v[],
DIGIT_T carry, size_t ndigits)
{
mpPrintHex("mpAdd: ", u, ndigits, " + ");
mpPrintHex("", v, ndigits, " = ");
mpPrintHex("", w, ndigits, ", ");
printf("carry = %" PRIxBIGD "\n", carry);
}
void ShowMult(DIGIT_T w[], DIGIT_T u[], DIGIT_T v[], size_t ndigits)
{
mpPrintHex("mpMultiply: ", u, ndigits, " x ");
mpPrintHex("", v, ndigits, " = ");
mpPrintHex("", w, ndigits*2, "\n");
}
void ShowDiv(DIGIT_T q[], DIGIT_T r[], DIGIT_T u[], DIGIT_T v[], size_t ndigits)
{
mpPrintHex("mpDivide: ", u, ndigits, " / ");
mpPrintHex("", v, ndigits, " = ");
mpPrintHex("", q, ndigits, " ");
mpPrintHex("rem ", r, ndigits, "\n");
}
int main(void)
{
DIGIT_T carry, m;
int jac;
size_t len;
size_t NDIGITS;
/* Force linker to include copyright notice in
executable object image
*/
copyright_notice();
ClearAll();
printf("Testing BIGDIGITS 'mp' functions.\n");
/* Start easy: 1 + 1 = 2 */
mpSetDigit(u, 1, TEST_LEN); /* u = 1 */
carry = mpAdd(w, u, u, TEST_LEN); /* w = u + u */
ShowAdd(w, u, u, carry, TEST_LEN);
/* Check that w == 2 */
assert(mpShortCmp(w, 2, TEST_LEN) == 0);
/* ---- Add and subtract ---- */
/* Add two random numbers w = u + v */
MakeMultipleRandom(u, TEST_LEN-1);
MakeMultipleRandom(v, TEST_LEN-1);
carry = mpAdd(w, u, v, TEST_LEN);
/* r = w - v */
carry = mpSubtract(r, w, v, TEST_LEN);
/* Check r == u */
assert(mpEqual(r, u, TEST_LEN));
printf("Add and subtract worked OK\n");
ClearAll();
/* ---- Multiply and divide ---- */
/* Multiply two random numbers w = u * v */
MakeMultipleRandom(u, TEST_LEN / 2);
MakeMultipleRandom(v, TEST_LEN / 2);
mpMultiply(w, u, v, TEST_LEN / 2);
if (debug) ShowMult(w, u, v, TEST_LEN / 2);
/* q = w / v, r = w % v */
mpDivide(q, r, w, TEST_LEN, v, TEST_LEN / 2);
/* Check q == u and r == 0 */
if (debug) mpPrintHex("q=", q, TEST_LEN / 2, "\n");
assert(mpEqual(q, u, TEST_LEN / 2));
assert(mpIsZero(r, TEST_LEN / 2));
ClearAll();
mpSetDigit(a, 0, TEST_LEN);
mpSetZero(n, TEST_LEN);
assert(mpEqual(a, n, TEST_LEN));
ClearAll();
/* Pick two random numbers u, v */
MakeMultipleRandom(u, TEST_LEN/2);
MakeMultipleRandom(v, TEST_LEN/2);
/* Divide one by the other: q = u / v, r = u % v */
mpDivide(q, r, u, TEST_LEN/2, v, TEST_LEN/2);
if (debug) ShowDiv(q, r, u, v, TEST_LEN/2);
/* Check w = q * v + r == u */
mpMultiply(g, q, v, TEST_LEN/2);
mpAdd(w, g, r, TEST_LEN/2);
assert(mpEqual(w, u, TEST_LEN/2));
printf("Multiply and divide worked OK\n");
/* ---- Greatest Common Divisor ---- */
/* Pick 3x random primes p1, p2, p3 */
printf("Creating 3 prime numbers (be patient):\n");
MakeMultiplePrime(p1, TEST_LEN / 2);
printf("(1)\n");
MakeMultiplePrime(p2, TEST_LEN / 2);
printf("(2)\n");
MakeMultiplePrime(p3, TEST_LEN / 2);
printf("(3)\n");
/* Calculate two products from these primes */
/* u = p1 * p2 */
mpMultiply(u, p1, p2, TEST_LEN / 2);
/* v = p1 * p3 */
mpMultiply(v, p1, p3, TEST_LEN / 2);
/* Now calculate g = gcd(u, v) */
mpGcd(g, u, v, TEST_LEN);
/* And check that g == p1 */
assert(mpEqual(g, p1, TEST_LEN));
printf("Greatest Common Divisor worked OK\n");
/* ---- Modular Inverse ---- */
/* Use previous prime as modulus, v */
mpSetEqual(v, p1, TEST_LEN);
/* Pick a small multiplier, m */
m = spSimpleRand(1, MAX_DIGIT);
/* Set u = (vm - 1) */
mpShortMult(u, v, m, TEST_LEN);
mpShortSub(u, u, 1, TEST_LEN);
mpModInv(w, u, v, TEST_LEN);
/* Check that g = (w * u) mod v = 1 */
mpModMult(g, w, u, v, TEST_LEN);
assert((mpShortCmp(g, 1, TEST_LEN) == 0));
printf("Modular inverse worked OK\n");
/* Compute some Jacobi and Legendre symbol values */
mpSetDigit(a, 158, TEST_LEN);
mpSetDigit(n, 235, TEST_LEN);
jac = mpJacobi(a, n, TEST_LEN);
//printf("Jacobi(158, 235)=%d\n", jac);
assert(-1 == jac);
mpSetDigit(a, 2183, TEST_LEN);
mpSetDigit(n, 9907, TEST_LEN);
jac = mpJacobi(a, n, TEST_LEN);
//printf("Jacobi(2183, 9907)=%d\n", jac);
assert(1 == jac);
mpSetDigit(a, 1001, TEST_LEN);
jac = mpJacobi(a, n, TEST_LEN);
//printf("Jacobi(1001, 9907)=%d\n", jac);
assert(-1 == jac);
mpShortMult(a, n, 10000, TEST_LEN);
jac = mpJacobi(a, n, TEST_LEN);
//printf("Jacobi(10000 * 9907, 9907)=%d\n", jac);
assert(0 == jac);
printf("Jacobi symbol tests worked OK\n");
/* ---- Square, square root and cube root ---- */
printf("\nSquare roots, etc...\n");
/* Pick a random number u */
MakeMultipleRandom(u, TEST_LEN/2);
mpPrintHex("u=", u, TEST_LEN/2, "\n");
/* Compute square */
mpSquare(v, u, TEST_LEN/2);
mpPrintHex("u^2=", v, TEST_LEN, "\n");
/* Compute square root */
mpSqrt(r, v, TEST_LEN);
mpPrintHex("sqrt(u^2)=", r, TEST_LEN, "\n");
/* Now compute square root of v - 1 */
mpShortSub(v, v, 1, TEST_LEN);
mpSqrt(w, v, TEST_LEN);
mpPrintHex("sqrt(u^2-1)=", w, TEST_LEN, "\n");
/* This should be one less than before */
mpSubtract(g, r, w, TEST_LEN);
mpPrintHex("difference=", g, TEST_LEN, " (expecting 1)\n");
assert(mpShortCmp(g, 1, TEST_LEN) == 0);
/* Compute cube */
ClearAll();
/* Pick another random number u */
len = TEST_LEN/4;
MakeMultipleRandom(u, len);
mpPrintHex("u=", u, len, "\n");
/* Compute cube (NB we use LEN/4 to avoid overflow on 2nd multiplication) */
mpSquare(w, u, len);
len = 2 * len;
mpMultiply(v, w, u, len);
mpPrintHex("u^3=", v, TEST_LEN, "\n");
/* Compute cube root */
mpCubeRoot(r, v, TEST_LEN);
mpPrintHex("cuberoot(u^3)=", r, TEST_LEN, "\n");
assert(mpCompare(r, u, TEST_LEN) == 0);
/* Now compute cube root of v - 1 */
mpShortSub(v, v, 1, TEST_LEN);
mpCubeRoot(w, v, TEST_LEN);
mpPrintHex("cuberoot(u^3-1)=", w, TEST_LEN, "\n");
/* This should be one less than before */
mpSubtract(g, r, w, TEST_LEN);
mpPrintHex("difference=", g, TEST_LEN, " (expecting 1)\n");
assert(mpShortCmp(g, 1, TEST_LEN) == 0);
printf("Testing signed arithmetic...\n");
NDIGITS = 4;
mpSetDigit(u, 2, NDIGITS);
mpSetDigit(v, 5, NDIGITS);
mpSubtract(w, u, v, NDIGITS);
mpPrintDecimalSigned("signed w=", w, NDIGITS, "\n");
mpPrintHex("unsigned w=0x", w, NDIGITS, "\n");
/* Display version number */
printf("\nVersion=%d\n", mpVersion());
/* For further checks do RSA calculation - see t_mpRSA.c */
printf("OK, successfully completed tests.\n");
return 0;
}

View File

@ -1,208 +1,208 @@
/* $Id: t_spExtras.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* Some tests for `extra' single-precision functions
-- some tests assume word size >= 32 bits
*/
#include <stdio.h>
#include <assert.h>
#include "bigdigits.h"
#include "spExtras.h"
#ifndef NELEMS
#define NELEMS(x) ((sizeof(x)) / (sizeof((x)[0])))
#endif /* NELEMS */
static int is_in_list(DIGIT_T a, DIGIT_T *list, size_t n)
/* Returns true (1) if a is in list of n elements; else false (0) */
{
size_t i;
int result = 0;
for (i = 0; i < n; i++)
{
if (a == list[i])
{
result = 1;
break;
}
}
return result;
}
int main(void)
{
DIGIT_T x, y, g;
DIGIT_T m, e, n, c, z, t;
DIGIT_T p, v, u, w, a, q;
int res, i, ntries;
DIGIT_T primes32[] = { 5, 17, 65, 99 };
DIGIT_T primes16[] = { 15, 17, 39 };
/* Test greatest common divisor (gcd) */
printf("Test spGcd:\n");
/* simple one */
x = 15; y = 27;
g = spGcd(x, y);
printf("gcd(%" PRIuBIGD ", %" PRIuBIGD ") = %" PRIuBIGD "\n", x, y, g);
assert(g == 3);
/* contrived using small primes */
x = 53 * 37; y = 53 * 83;
g = spGcd(x, y);
printf("gcd(%" PRIuBIGD ", %" PRIuBIGD ") = %" PRIuBIGD "\n", x, y, g);
assert(g == 53);
/* contrived using bigger primes */
x = 0x0345 * 0xfedc; y = 0xfedc * 0x0871;
g = spGcd(x, y);
printf("gcd(0x%" PRIxBIGD ", 0x%" PRIxBIGD ") = 0x%" PRIxBIGD "\n", x, y, g);
assert(g == 0xfedc);
/* Known primes: 2^16-15, 2^32-5 */
y = 0x10000 - 15;
x = spSimpleRand(1, y);
g = spGcd(x, y);
printf("gcd(0x%" PRIxBIGD ", 0x%" PRIxBIGD ") = %" PRIxBIGD "\n", x, y, g);
assert(g == 1);
y = 0xffffffff - 5 + 1;
x = spSimpleRand(1, y);
g = spGcd(x, y);
printf("gcd(0x%" PRIxBIGD ", 0x%" PRIxBIGD ") = %" PRIxBIGD "\n", x, y, g);
assert(g == 1);
/* Test spModExp */
printf("Test spModExp:\n");
/* Verify that (m^e mod n).(z^e mod n) == (m.z)^e mod n
for random m, e, n, z */
/* Generate some random numbers */
n = spSimpleRand(MAX_DIGIT / 2, MAX_DIGIT);
m = spSimpleRand(1, n -1);
e = spSimpleRand(1, n -1);
z = spSimpleRand(1, n -1);
/* Compute c = m^e mod n */
spModExp(&c, m, e, n);
printf("c=m^e mod n=%" PRIxBIGD "^%" PRIxBIGD " mod %" PRIxBIGD "=%" PRIxBIGD "\n", m, e, n, c);
/* Compute x = c.z^e mod n */
printf("z=%" PRIxBIGD "\n", z);
spModExp(&t, z, e, n);
spModMult(&x, c, t, n);
printf("x = c.z^e mod n = %" PRIxBIGD "\n", x);
/* Compute y = (m.z)^e mod n */
spModMult(&t, m, z, n);
spModExp(&y, t, e, n);
printf("y = (m.z)^e mod n = %" PRIxBIGD "\n", x);
/* Check they are equal */
assert(x == y);
/* Test spModInv */
printf("Test spModInv:\n");
/* Use identity that (vp-1)^-1 mod p = p-1
for prime p and integer v */
/* known prime */
p = 0x10000 - 15;
/* small multiplier */
v = spSimpleRand(2, 10);
u = v * p - 1;
printf("u = vp-1 = %" PRIuBIGD " * %" PRIuBIGD " - 1 = %" PRIuBIGD "\n", v, p, u);
/* compute w = u^-1 mod p */
spModInv(&w, u, p);
printf("w = u^-1 mod p = %" PRIuBIGD "\n", w);
/* check wu mod p == 1 */
spModMult(&c, w, u, p);
printf("Check 1 == wu mod p = %" PRIuBIGD "\n", c);
assert(c == 1);
/* Try mod inversion that should fail */
/* Set u = pq so that gcd(u, p) != 1 */
q = 31;
u = p * q;
printf("p=%" PRIuBIGD " q=%" PRIuBIGD " pq=%" PRIuBIGD "\n", p, q, u);
printf("gcd(pq, p) = %" PRIuBIGD " (i.e. not 1)\n", spGcd(u, p));
res = spModInv(&w, u, p);
printf("w = (pq)^-1 mod p returns error %d (expected 1)\n", res);
assert(res != 0);
/* Test spIsPrime */
printf("Test spIsPrime:\n");
/* Find primes just less than 2^32. Ref: Knuth p408 */
for (n = 0xffffffff, a = 1; a < 100; a++, n--)
{
if (spIsPrime(n, 50))
{
printf("2^32-%" PRIuBIGD " is prime\n", a);
assert(is_in_list(a, primes32, NELEMS(primes32)));
}
}
/* And just less than 2^16 */
for (n = 0xffff, a = 1; a < 50; a++, n--)
{
if (spIsPrime(n, 50))
{
printf("2^16-%" PRIuBIGD " is prime\n", a);
assert(is_in_list(a, primes16, NELEMS(primes16)));
}
}
/* Generate a random prime < MAX_DIGIT */
n = spSimpleRand(0, MAX_DIGIT);
/* make sure odd */
n |= 0x01;
/* expect to find a prime approx every lg(n) numbers,
so for sure within 100 times that */
ntries = BITS_PER_DIGIT * 100;
for (i = 0; i < ntries; i++)
{
if (spIsPrime(n, 50))
break;
n += 2;
}
printf("Random prime, n = %" PRIuBIGD " (0x%" PRIxBIGD ")\n", n, n);
printf("found after %d candidates\n", i+1);
if (i >= ntries)
printf("Didn't manage to find a prime in %d tries!\n", ntries);
else
assert(spIsPrime(n, 50));
res = spIsPrime(n, 50);
printf("spIsPrime(%" PRIuBIGD ") is %s\n", n, (res ? "TRUE" : "FALSE"));
/* Check using (less accurate) Fermat test (these could fail) */
w = 2;
spModExp(&x, w, n-1, n);
printf("Fermat test: %" PRIxBIGD "^(n-1) mod n = %" PRIxBIGD " (%s)\n", w, x, (x == 1 ? "PASSED" : "FAILED!"));
w = 3;
spModExp(&x, w, n-1, n);
printf("Fermat test: %" PRIxBIGD "^(n-1) mod n = %" PRIxBIGD " (%s)\n", w, x, (x == 1 ? "PASSED" : "FAILED!"));
w = 5;
spModExp(&x, w, n-1, n);
printf("Fermat test: %" PRIxBIGD "^(n-1) mod n = %" PRIxBIGD " (%s)\n", w, x, (x == 1 ? "PASSED" : "FAILED!"));
/* Try a known Fermat liar (Carmichael number) */
n = 561;
printf("Try n = 561 = 3*11*17 (a 'Fermat liar')\n");
w = 5;
spModExp(&x, w, n-1, n);
printf("Fermat test: %" PRIxBIGD "^(n-1) mod n = %" PRIxBIGD " (%s)\n", w, x, (x == 1 ? "PASSED" : "FAILED!"));
res = spIsPrime(n, 50);
printf("spIsPrime(%" PRIuBIGD ") is %s\n", n, (res ? "TRUE" : "FALSE"));
assert(!res);
return 0;
}
/* $Id: t_spExtras.c $ */
/***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2001-15 David Ireland, D.I. Management Services Pty Limited
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
*
***** END LICENSE BLOCK *****/
/*
* Last updated:
* $Date: 2015-10-22 10:23:00 $
* $Revision: 2.5.0 $
* $Author: dai $
*/
/* Some tests for `extra' single-precision functions
-- some tests assume word size >= 32 bits
*/
#include <stdio.h>
#include <assert.h>
#include "bigdigits.h"
#include "spExtras.h"
#ifndef NELEMS
#define NELEMS(x) ((sizeof(x)) / (sizeof((x)[0])))
#endif /* NELEMS */
static int is_in_list(DIGIT_T a, DIGIT_T *list, size_t n)
/* Returns true (1) if a is in list of n elements; else false (0) */
{
size_t i;
int result = 0;
for (i = 0; i < n; i++)
{
if (a == list[i])
{
result = 1;
break;
}
}
return result;
}
int main(void)
{
DIGIT_T x, y, g;
DIGIT_T m, e, n, c, z, t;
DIGIT_T p, v, u, w, a, q;
int res, i, ntries;
DIGIT_T primes32[] = { 5, 17, 65, 99 };
DIGIT_T primes16[] = { 15, 17, 39 };
/* Test greatest common divisor (gcd) */
printf("Test spGcd:\n");
/* simple one */
x = 15; y = 27;
g = spGcd(x, y);
printf("gcd(%" PRIuBIGD ", %" PRIuBIGD ") = %" PRIuBIGD "\n", x, y, g);
assert(g == 3);
/* contrived using small primes */
x = 53 * 37; y = 53 * 83;
g = spGcd(x, y);
printf("gcd(%" PRIuBIGD ", %" PRIuBIGD ") = %" PRIuBIGD "\n", x, y, g);
assert(g == 53);
/* contrived using bigger primes */
x = 0x0345 * 0xfedc; y = 0xfedc * 0x0871;
g = spGcd(x, y);
printf("gcd(0x%" PRIxBIGD ", 0x%" PRIxBIGD ") = 0x%" PRIxBIGD "\n", x, y, g);
assert(g == 0xfedc);
/* Known primes: 2^16-15, 2^32-5 */
y = 0x10000 - 15;
x = spSimpleRand(1, y);
g = spGcd(x, y);
printf("gcd(0x%" PRIxBIGD ", 0x%" PRIxBIGD ") = %" PRIxBIGD "\n", x, y, g);
assert(g == 1);
y = 0xffffffff - 5 + 1;
x = spSimpleRand(1, y);
g = spGcd(x, y);
printf("gcd(0x%" PRIxBIGD ", 0x%" PRIxBIGD ") = %" PRIxBIGD "\n", x, y, g);
assert(g == 1);
/* Test spModExp */
printf("Test spModExp:\n");
/* Verify that (m^e mod n).(z^e mod n) == (m.z)^e mod n
for random m, e, n, z */
/* Generate some random numbers */
n = spSimpleRand(MAX_DIGIT / 2, MAX_DIGIT);
m = spSimpleRand(1, n -1);
e = spSimpleRand(1, n -1);
z = spSimpleRand(1, n -1);
/* Compute c = m^e mod n */
spModExp(&c, m, e, n);
printf("c=m^e mod n=%" PRIxBIGD "^%" PRIxBIGD " mod %" PRIxBIGD "=%" PRIxBIGD "\n", m, e, n, c);
/* Compute x = c.z^e mod n */
printf("z=%" PRIxBIGD "\n", z);
spModExp(&t, z, e, n);
spModMult(&x, c, t, n);
printf("x = c.z^e mod n = %" PRIxBIGD "\n", x);
/* Compute y = (m.z)^e mod n */
spModMult(&t, m, z, n);
spModExp(&y, t, e, n);
printf("y = (m.z)^e mod n = %" PRIxBIGD "\n", x);
/* Check they are equal */
assert(x == y);
/* Test spModInv */
printf("Test spModInv:\n");
/* Use identity that (vp-1)^-1 mod p = p-1
for prime p and integer v */
/* known prime */
p = 0x10000 - 15;
/* small multiplier */
v = spSimpleRand(2, 10);
u = v * p - 1;
printf("u = vp-1 = %" PRIuBIGD " * %" PRIuBIGD " - 1 = %" PRIuBIGD "\n", v, p, u);
/* compute w = u^-1 mod p */
spModInv(&w, u, p);
printf("w = u^-1 mod p = %" PRIuBIGD "\n", w);
/* check wu mod p == 1 */
spModMult(&c, w, u, p);
printf("Check 1 == wu mod p = %" PRIuBIGD "\n", c);
assert(c == 1);
/* Try mod inversion that should fail */
/* Set u = pq so that gcd(u, p) != 1 */
q = 31;
u = p * q;
printf("p=%" PRIuBIGD " q=%" PRIuBIGD " pq=%" PRIuBIGD "\n", p, q, u);
printf("gcd(pq, p) = %" PRIuBIGD " (i.e. not 1)\n", spGcd(u, p));
res = spModInv(&w, u, p);
printf("w = (pq)^-1 mod p returns error %d (expected 1)\n", res);
assert(res != 0);
/* Test spIsPrime */
printf("Test spIsPrime:\n");
/* Find primes just less than 2^32. Ref: Knuth p408 */
for (n = 0xffffffff, a = 1; a < 100; a++, n--)
{
if (spIsPrime(n, 50))
{
printf("2^32-%" PRIuBIGD " is prime\n", a);
assert(is_in_list(a, primes32, NELEMS(primes32)));
}
}
/* And just less than 2^16 */
for (n = 0xffff, a = 1; a < 50; a++, n--)
{
if (spIsPrime(n, 50))
{
printf("2^16-%" PRIuBIGD " is prime\n", a);
assert(is_in_list(a, primes16, NELEMS(primes16)));
}
}
/* Generate a random prime < MAX_DIGIT */
n = spSimpleRand(0, MAX_DIGIT);
/* make sure odd */
n |= 0x01;
/* expect to find a prime approx every lg(n) numbers,
so for sure within 100 times that */
ntries = BITS_PER_DIGIT * 100;
for (i = 0; i < ntries; i++)
{
if (spIsPrime(n, 50))
break;
n += 2;
}
printf("Random prime, n = %" PRIuBIGD " (0x%" PRIxBIGD ")\n", n, n);
printf("found after %d candidates\n", i+1);
if (i >= ntries)
printf("Didn't manage to find a prime in %d tries!\n", ntries);
else
assert(spIsPrime(n, 50));
res = spIsPrime(n, 50);
printf("spIsPrime(%" PRIuBIGD ") is %s\n", n, (res ? "TRUE" : "FALSE"));
/* Check using (less accurate) Fermat test (these could fail) */
w = 2;
spModExp(&x, w, n-1, n);
printf("Fermat test: %" PRIxBIGD "^(n-1) mod n = %" PRIxBIGD " (%s)\n", w, x, (x == 1 ? "PASSED" : "FAILED!"));
w = 3;
spModExp(&x, w, n-1, n);
printf("Fermat test: %" PRIxBIGD "^(n-1) mod n = %" PRIxBIGD " (%s)\n", w, x, (x == 1 ? "PASSED" : "FAILED!"));
w = 5;
spModExp(&x, w, n-1, n);
printf("Fermat test: %" PRIxBIGD "^(n-1) mod n = %" PRIxBIGD " (%s)\n", w, x, (x == 1 ? "PASSED" : "FAILED!"));
/* Try a known Fermat liar (Carmichael number) */
n = 561;
printf("Try n = 561 = 3*11*17 (a 'Fermat liar')\n");
w = 5;
spModExp(&x, w, n-1, n);
printf("Fermat test: %" PRIxBIGD "^(n-1) mod n = %" PRIxBIGD " (%s)\n", w, x, (x == 1 ? "PASSED" : "FAILED!"));
res = spIsPrime(n, 50);
printf("spIsPrime(%" PRIuBIGD ") is %s\n", n, (res ? "TRUE" : "FALSE"));
assert(!res);
return 0;
}

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <debug.h>
#include <console.h>
#include <platform.h>

View File

@ -1,3 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
include lib/cpu/${BOOT_CPU}/cpu-ops.mk
ASFLAGS +=\

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <mmio.h>
#include <debug.h>
#include <assert.h>

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef _RISCV_BITS_H
#define _RISCV_BITS_H

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include "bits.h"
#include "csr.h"
#include <platform.h>

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include "bits.h"
#include "csr.h"
#include <riscv/asm_macros.S>

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <debug.h>
#include <console.h>
#include <platform.h>

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <platform.h>
#include <arch_helpers.h>

View File

@ -1,4 +1,4 @@
#include lib/cpu/${BOOT_CPU}/cpu-ops.mk
# SPDX-License-Identifier: BSD-3-Clause
ASFLAGS +=\
$(CPPFLAGS) \
@ -38,9 +38,7 @@ CPU_SOURCES := \
BL1_CPU_SOURCES := \
lib/cpu/${BOOT_CPU}/bl1_entrypoint.S \
# lib/cpu/${BOOT_CPU}/bl1_exceptions.S
lib/cpu/${BOOT_CPU}/bl1_entrypoint.S
BL2_CPU_SOURCES := \
lib/cpu/${BOOT_CPU}/bl2_entrypoint.S \
# lib/cpu/${BOOT_CPU}/bl2_exceptions.S
lib/cpu/${BOOT_CPU}/bl2_entrypoint.S

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <mmio.h>
#include <debug.h>
#include <assert.h>

View File

@ -1,4 +1,4 @@
// See LICENSE for license details.
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef RISCV_CSR_ENCODING_H
#define RISCV_CSR_ENCODING_H

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <string.h>
void *memcpy16(void *dest, const void *src, size_t length)

View File

@ -1,29 +1,29 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tommath", "libtommath_VS2008.vcproj", "{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|Win32.ActiveCfg = Debug|Win32
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|Win32.Build.0 = Debug|Win32
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|x64.ActiveCfg = Debug|x64
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|x64.Build.0 = Debug|x64
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|Win32.ActiveCfg = Release|Win32
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|Win32.Build.0 = Release|Win32
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|x64.ActiveCfg = Release|x64
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {83B84178-7B4F-4B78-9C5D-17B8201D5B61}
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tommath", "libtommath_VS2008.vcproj", "{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|Win32.ActiveCfg = Debug|Win32
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|Win32.Build.0 = Debug|Win32
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|x64.ActiveCfg = Debug|x64
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|x64.Build.0 = Debug|x64
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|Win32.ActiveCfg = Release|Win32
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|Win32.Build.0 = Release|Win32
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|x64.ActiveCfg = Release|x64
{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {83B84178-7B4F-4B78-9C5D-17B8201D5B61}
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load Diff

View File

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <stdint.h>
#include <ctype.h>
#include <string.h>

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <debug.h>
#include <errno.h>
#include <string.h>
@ -119,9 +121,6 @@ int decompress_lz4(void *dst, size_t *dst_size, const void *src, size_t src_size
return -1;
}
// No need to free.
// LZ4F_freeDecompressionContext(dctx);
return 0;
}

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef __DECOMPRESS_H__
#define __DECOMPRESS_H__

View File

@ -1,3 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
BLCP_PATH = ../fast_image_mcu/riscv/output/fast_image_mcu.bin
ifeq ("$(wildcard $(BLCP_PATH))","")
BLCP_PATH = test/empty.bin
@ -16,7 +18,7 @@ fip%: export BLCP_IMG_RUNADDR=0x05200200
fip%: export BLCP_PARAM_LOADADDR=0
fip%: export NAND_INFO=00000000
fip%: export NOR_INFO=$(shell printf '%72s' | tr ' ' 'FF')
fip%: export DDR_PARAM_TEST_PATH = test/cv181x/ddr_param.bin
fip%: export DDR_PARAM_TEST_PATH = test/sophon/ddr_param.bin
${BUILD_PLAT}:
@mkdir -p '${BUILD_PLAT}'

View File

@ -1,3 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <platform.h>
#include <cdefs.h>

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause
# PYTHON_ARGCOMPLETE_OK
import sys

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
#include <debug.h>
#include <console.h>
#include <platform.h>
@ -5,6 +7,10 @@
#include <string.h>
#include <delay_timer.h>
#define UART_DLL 0x04140000
#define UART_DLH 0x04140004
#define UART_LCR 0x0414000C
#ifdef RTOS_ENABLE_FREERTOS
int init_comm_info(int ret)
{
@ -46,11 +52,6 @@ int dec_verify_image(const void *image, size_t size, size_t dec_skip, struct fip
}
#endif
// Start of addition
#define UART_DLL 0x04140000
#define UART_DLH 0x04140004
#define UART_LCR 0x0414000C
void set_baudrate()
{
// 14 for 115200, 13 for 128000
@ -66,14 +67,11 @@ void set_baudrate()
// set DLAB back to 0
*(volatile uint32_t*)(UART_LCR) &= (uint32_t)(~0x80);
}
// End of addition
void bl2_main(void)
{
// Start of addition
set_baudrate();
// End of addition
ATF_STATE = ATF_STATE_BL2_MAIN;
time_records->fsbl_start = read_time_ms();
@ -85,7 +83,6 @@ void bl2_main(void)
INFO("CP_STATE_REG=0x%x\n", mmio_read_32(0x0E000018));
// print_sram_log();
lock_efuse_chipsn();
setup_dl_flag();

View File

@ -0,0 +1,536 @@
/*
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <debug.h>
#include <bitwise_ops.h>
#include <console.h>
#include <platform.h>
#include <rom_api.h>
#include <bl2.h>
#include <ddr.h>
#include <string.h>
#include <decompress.h>
#include <delay_timer.h>
#include <security/security.h>
#include <cv_usb.h>
struct _time_records *time_records = (void *)TIME_RECORDS_ADDR;
struct fip_param1 *fip_param1 = (void *)PARAM1_BASE;
static struct fip_param2 fip_param2 __aligned(BLOCK_SIZE);
static union {
struct ddr_param ddr_param;
struct loader_2nd_header loader_2nd_header;
uint8_t buf[BLOCK_SIZE];
} sram_union_buf __aligned(BLOCK_SIZE);
int init_comm_info(int ret) __attribute__((weak));
int init_comm_info(int ret)
{
return ret;
}
void print_sram_log(void)
{
uint32_t *const log_size = (void *)BOOT_LOG_LEN_ADDR;
uint8_t *const log_buf = (void *)phys_to_dma(BOOT_LOG_BUF_BASE);
uint32_t i;
static const char m1[] = "\nSRAM Log: ========================================\n";
static const char m2[] = "\nSRAM Log end: ====================================\n";
for (i = 0; m1[i]; i++)
console_putc(m1[i]);
for (i = 0; i < *log_size; i++)
console_putc(log_buf[i]);
for (i = 0; m2[i]; i++)
console_putc(m2[i]);
}
void lock_efuse_chipsn(void)
{
int value = mmio_read_32(EFUSE_W_LOCK0_REG);
if (efuse_power_on()) {
NOTICE("efuse power on fail\n");
return;
}
if ((value & (0x1 << BIT_FTSN3_LOCK)) == 0)
efuse_program_bit(0x26, BIT_FTSN3_LOCK);
if ((value & (0x1 << BIT_FTSN4_LOCK)) == 0)
efuse_program_bit(0x26, BIT_FTSN4_LOCK);
if (efuse_refresh_shadow()) {
NOTICE("efuse refresh shadow fail\n");
return;
}
value = mmio_read_32(EFUSE_W_LOCK0_REG);
if (((value & (0x3 << BIT_FTSN3_LOCK)) >> BIT_FTSN3_LOCK) != 0x3)
NOTICE("lock efuse chipsn fail\n");
if (efuse_power_off()) {
NOTICE("efuse power off fail\n");
return;
}
}
#ifdef USB_DL_BY_FSBL
int load_image_by_usb(void *buf, uint32_t offset, size_t image_size, int retry_num)
{
int ret = -1;
if (usb_polling(buf, offset, image_size) == CV_USB_DL)
ret = 0;
else
ret = -2;
INFO("LIE/%d/%p/0x%x/%lu.\n", ret, buf, offset, image_size);
return ret;
}
#endif
int load_param2(int retry)
{
uint32_t crc;
int ret = -1;
NOTICE("P2S/0x%lx/%p.\n", sizeof(fip_param2), &fip_param2);
#ifdef USB_DL_BY_FSBL
if (p_rom_api_get_boot_src() == BOOT_SRC_USB)
ret = load_image_by_usb(&fip_param2, fip_param1->param2_loadaddr, PARAM2_SIZE, retry);
else
#endif
ret = p_rom_api_load_image(&fip_param2, fip_param1->param2_loadaddr, PARAM2_SIZE, retry);
if (ret < 0) {
return ret;
}
if (fip_param2.magic1 != FIP_PARAM2_MAGIC1) {
WARN("LP2_NOMAGIC\n");
return -1;
}
crc = p_rom_api_image_crc(&fip_param2.reserved1, sizeof(fip_param2) - 12);
if (crc != fip_param2.param2_cksum) {
ERROR("param2_cksum (0x%x/0x%x)\n", crc, fip_param2.param2_cksum);
return -1;
}
NOTICE("P2E.\n");
return 0;
}
int load_ddr_param(int retry)
{
uint32_t crc;
int ret = -1;
NOTICE("DPS/0x%x/0x%x.\n", fip_param2.ddr_param_loadaddr, fip_param2.ddr_param_size);
if (fip_param2.ddr_param_size >= sizeof(sram_union_buf.ddr_param))
fip_param2.ddr_param_size = sizeof(sram_union_buf.ddr_param);
#ifdef USB_DL_BY_FSBL
if (p_rom_api_get_boot_src() == BOOT_SRC_USB)
ret = load_image_by_usb(&sram_union_buf.ddr_param, fip_param2.ddr_param_loadaddr,
fip_param2.ddr_param_size, retry);
else
#endif
ret = p_rom_api_load_image(&sram_union_buf.ddr_param, fip_param2.ddr_param_loadaddr,
fip_param2.ddr_param_size, retry);
if (ret < 0) {
return ret;
}
crc = p_rom_api_image_crc(&sram_union_buf.ddr_param, fip_param2.ddr_param_size);
if (crc != fip_param2.ddr_param_cksum) {
ERROR("ddr_param_cksum (0x%x/0x%x)\n", crc, fip_param2.ddr_param_cksum);
return -1;
}
NOTICE("DPE.\n");
return 0;
}
int load_ddr(void)
{
int retry = 0;
retry_from_flash:
for (retry = 0; retry < p_rom_api_get_number_of_retries(); retry++) {
if (load_param2(retry) < 0)
continue;
if (load_ddr_param(retry) < 0)
continue;
break;
}
if (retry >= p_rom_api_get_number_of_retries()) {
switch (p_rom_api_get_boot_src()) {
case BOOT_SRC_UART:
case BOOT_SRC_SD:
case BOOT_SRC_USB:
WARN("DL cancelled. Load flash. (%d).\n", retry);
// Continue to boot from flash if boot from external source
p_rom_api_flash_init();
goto retry_from_flash;
default:
ERROR("Failed to load DDR param (%d).\n", retry);
panic_handler();
}
}
time_records->ddr_init_start = read_time_ms();
ddr_init(&sram_union_buf.ddr_param);
time_records->ddr_init_end = read_time_ms();
return 0;
}
int load_blcp_2nd(int retry)
{
uint32_t crc, rtos_base;
int ret = -1;
// if no blcp_2nd, release_blcp_2nd should be ddr_init_end
time_records->release_blcp_2nd = time_records->ddr_init_end;
NOTICE("C2S/0x%x/0x%x/0x%x.\n", fip_param2.blcp_2nd_loadaddr, fip_param2.blcp_2nd_runaddr,
fip_param2.blcp_2nd_size);
if (!fip_param2.blcp_2nd_runaddr) {
NOTICE("No C906L image.\n");
return 0;
}
if (!IN_RANGE(fip_param2.blcp_2nd_runaddr, DRAM_BASE, DRAM_SIZE)) {
ERROR("blcp_2nd_runaddr (0x%x) is not in DRAM.\n", fip_param2.blcp_2nd_runaddr);
panic_handler();
}
if (!IN_RANGE(fip_param2.blcp_2nd_runaddr + fip_param2.blcp_2nd_size, DRAM_BASE, DRAM_SIZE)) {
ERROR("blcp_2nd_size (0x%x) is not in DRAM.\n", fip_param2.blcp_2nd_size);
panic_handler();
}
#ifdef USB_DL_BY_FSBL
if (p_rom_api_get_boot_src() == BOOT_SRC_USB)
ret = load_image_by_usb((void *)(uintptr_t)fip_param2.blcp_2nd_runaddr, fip_param2.blcp_2nd_loadaddr,
fip_param2.blcp_2nd_size, retry);
else
#endif
ret = p_rom_api_load_image((void *)(uintptr_t)fip_param2.blcp_2nd_runaddr, fip_param2.blcp_2nd_loadaddr,
fip_param2.blcp_2nd_size, retry);
if (ret < 0) {
return ret;
}
crc = p_rom_api_image_crc((void *)(uintptr_t)fip_param2.blcp_2nd_runaddr, fip_param2.blcp_2nd_size);
if (crc != fip_param2.blcp_2nd_cksum) {
ERROR("blcp_2nd_cksum (0x%x/0x%x)\n", crc, fip_param2.blcp_2nd_cksum);
return -1;
}
ret = dec_verify_image((void *)(uintptr_t)fip_param2.blcp_2nd_runaddr, fip_param2.blcp_2nd_size, 0, fip_param1);
if (ret < 0) {
ERROR("verify blcp 2nd (%d)\n", ret);
return ret;
}
flush_dcache_range(fip_param2.blcp_2nd_runaddr, fip_param2.blcp_2nd_size);
rtos_base = mmio_read_32(AXI_SRAM_RTOS_BASE);
init_comm_info(0);
time_records->release_blcp_2nd = read_time_ms();
if (rtos_base == CVI_RTOS_MAGIC_CODE) {
mmio_write_32(AXI_SRAM_RTOS_BASE, fip_param2.blcp_2nd_runaddr);
} else {
reset_c906l(fip_param2.blcp_2nd_runaddr);
}
NOTICE("C2E.\n");
return 0;
}
int load_monitor(int retry, uint64_t *monitor_entry)
{
uint32_t crc;
int ret = -1;
NOTICE("MS/0x%x/0x%x/0x%x.\n", fip_param2.monitor_loadaddr, fip_param2.monitor_runaddr,
fip_param2.monitor_size);
if (!fip_param2.monitor_runaddr) {
NOTICE("No monitor.\n");
return 0;
}
if (!IN_RANGE(fip_param2.monitor_runaddr, DRAM_BASE, DRAM_SIZE)) {
ERROR("monitor_runaddr (0x%x) is not in DRAM.\n", fip_param2.monitor_runaddr);
panic_handler();
}
if (!IN_RANGE(fip_param2.monitor_runaddr + fip_param2.monitor_size, DRAM_BASE, DRAM_SIZE)) {
ERROR("monitor_size (0x%x) is not in DRAM.\n", fip_param2.monitor_size);
panic_handler();
}
#ifdef USB_DL_BY_FSBL
if (p_rom_api_get_boot_src() == BOOT_SRC_USB)
ret = load_image_by_usb((void *)(uintptr_t)fip_param2.monitor_runaddr, fip_param2.monitor_loadaddr,
fip_param2.monitor_size, retry);
else
#endif
ret = p_rom_api_load_image((void *)(uintptr_t)fip_param2.monitor_runaddr, fip_param2.monitor_loadaddr,
fip_param2.monitor_size, retry);
if (ret < 0) {
return ret;
}
crc = p_rom_api_image_crc((void *)(uintptr_t)fip_param2.monitor_runaddr, fip_param2.monitor_size);
if (crc != fip_param2.monitor_cksum) {
ERROR("monitor_cksum (0x%x/0x%x)\n", crc, fip_param2.monitor_cksum);
return -1;
}
ret = dec_verify_image((void *)(uintptr_t)fip_param2.monitor_runaddr, fip_param2.monitor_size, 0, fip_param1);
if (ret < 0) {
ERROR("verify monitor (%d)\n", ret);
return ret;
}
flush_dcache_range(fip_param2.monitor_runaddr, fip_param2.monitor_size);
NOTICE("ME.\n");
*monitor_entry = fip_param2.monitor_runaddr;
return 0;
}
int load_loader_2nd(int retry, uint64_t *loader_2nd_entry)
{
struct loader_2nd_header *loader_2nd_header = &sram_union_buf.loader_2nd_header;
uint32_t crc;
int ret = -1;
const int cksum_offset =
offsetof(struct loader_2nd_header, cksum) + sizeof(((struct loader_2nd_header *)0)->cksum);
enum COMPRESS_TYPE comp_type = COMP_NONE;
int reading_size;
void *image_buf;
NOTICE("L2/0x%x.\n", fip_param2.loader_2nd_loadaddr);
#ifdef USB_DL_BY_FSBL
if (p_rom_api_get_boot_src() == BOOT_SRC_USB)
ret = load_image_by_usb(loader_2nd_header, fip_param2.loader_2nd_loadaddr, BLOCK_SIZE, retry);
else
#endif
ret = p_rom_api_load_image(loader_2nd_header, fip_param2.loader_2nd_loadaddr, BLOCK_SIZE, retry);
if (ret < 0) {
return -1;
}
reading_size = ROUND_UP(loader_2nd_header->size, BLOCK_SIZE);
NOTICE("L2/0x%x/0x%x/0x%lx/0x%x/0x%x\n", loader_2nd_header->magic, loader_2nd_header->cksum,
loader_2nd_header->runaddr, loader_2nd_header->size, reading_size);
switch (loader_2nd_header->magic) {
case LOADER_2ND_MAGIC_LZMA:
comp_type = COMP_LZMA;
break;
case LOADER_2ND_MAGIC_LZ4:
comp_type = COMP_LZ4;
break;
default:
comp_type = COMP_NONE;
break;
}
if (comp_type) {
NOTICE("COMP/%d.\n", comp_type);
image_buf = (void *)DECOMP_BUF_ADDR;
} else {
image_buf = (void *)loader_2nd_header->runaddr;
}
#ifdef USB_DL_BY_FSBL
if (p_rom_api_get_boot_src() == BOOT_SRC_USB)
ret = load_image_by_usb(image_buf, fip_param2.loader_2nd_loadaddr, reading_size, retry);
else
#endif
ret = p_rom_api_load_image(image_buf, fip_param2.loader_2nd_loadaddr, reading_size, retry);
if (ret < 0) {
return -1;
}
crc = p_rom_api_image_crc(image_buf + cksum_offset, loader_2nd_header->size - cksum_offset);
if (crc != loader_2nd_header->cksum) {
ERROR("loader_2nd_cksum (0x%x/0x%x)\n", crc, loader_2nd_header->cksum);
return -1;
}
ret = dec_verify_image(image_buf + cksum_offset, loader_2nd_header->size - cksum_offset,
sizeof(struct loader_2nd_header) - cksum_offset, fip_param1);
if (ret < 0) {
ERROR("verify loader 2nd (%d)\n", ret);
return ret;
}
time_records->load_loader_2nd_end = read_time_ms();
sys_switch_all_to_pll();
time_records->fsbl_decomp_start = read_time_ms();
if (comp_type) {
size_t dst_size = DECOMP_DST_SIZE;
// header is not compressed.
void *dst = (void *)loader_2nd_header->runaddr;
memcpy(dst, image_buf, sizeof(struct loader_2nd_header));
image_buf += sizeof(struct loader_2nd_header);
ret = decompress(dst + sizeof(struct loader_2nd_header), &dst_size, image_buf, loader_2nd_header->size,
comp_type);
if (ret < 0) {
ERROR("Failed to decompress loader_2nd (%d/%lu)\n", ret, dst_size);
return -1;
}
reading_size = dst_size;
}
flush_dcache_range(loader_2nd_header->runaddr, reading_size);
time_records->fsbl_decomp_end = read_time_ms();
NOTICE("Loader_2nd loaded.\n");
*loader_2nd_entry = loader_2nd_header->runaddr + sizeof(struct loader_2nd_header);
return 0;
}
int load_rest(void)
{
int retry = 0;
uint64_t monitor_entry = 0;
uint64_t loader_2nd_entry = 0;
// Init sys PLL and switch clocks to PLL
sys_pll_init();
retry_from_flash:
for (retry = 0; retry < p_rom_api_get_number_of_retries(); retry++) {
if (load_blcp_2nd(retry) < 0)
continue;
if (load_monitor(retry, &monitor_entry) < 0)
continue;
if (load_loader_2nd(retry, &loader_2nd_entry) < 0)
continue;
break;
}
if (retry >= p_rom_api_get_number_of_retries()) {
switch (p_rom_api_get_boot_src()) {
case BOOT_SRC_UART:
case BOOT_SRC_SD:
case BOOT_SRC_USB:
WARN("DL cancelled. Load flash. (%d).\n", retry);
// Continue to boot from flash if boot from external source
p_rom_api_flash_init();
goto retry_from_flash;
default:
ERROR("Failed to load rest (%d).\n", retry);
panic_handler();
}
}
sync_cache();
console_flush();
switch_rtc_mode_2nd_stage();
if (monitor_entry) {
NOTICE("Jump to monitor at 0x%lx.\n", monitor_entry);
jump_to_monitor(monitor_entry, loader_2nd_entry);
} else {
NOTICE("Jump to loader_2nd at 0x%lx.\n", loader_2nd_entry);
jump_to_loader_2nd(loader_2nd_entry);
}
return 0;
}
int load_rest_od_sel(void)
{
int retry = 0;
uint64_t monitor_entry = 0;
uint64_t loader_2nd_entry = 0;
// Init sys PLL and switch clocks to PLL
sys_pll_init_od_sel();
retry_from_flash:
for (retry = 0; retry < p_rom_api_get_number_of_retries(); retry++) {
if (load_blcp_2nd(retry) < 0)
continue;
if (load_monitor(retry, &monitor_entry) < 0)
continue;
if (load_loader_2nd(retry, &loader_2nd_entry) < 0)
continue;
break;
}
if (retry >= p_rom_api_get_number_of_retries()) {
switch (p_rom_api_get_boot_src()) {
case BOOT_SRC_UART:
case BOOT_SRC_SD:
case BOOT_SRC_USB:
WARN("DL cancelled. Load flash. (%d).\n", retry);
// Continue to boot from flash if boot from external source
p_rom_api_flash_init();
goto retry_from_flash;
default:
ERROR("Failed to load rest (%d).\n", retry);
panic_handler();
}
}
sync_cache();
console_flush();
switch_rtc_mode_2nd_stage();
if (monitor_entry) {
NOTICE("Jump to monitor at 0x%lx.\n", monitor_entry);
jump_to_monitor(monitor_entry, loader_2nd_entry);
} else {
NOTICE("Jump to loader_2nd at 0x%lx.\n", loader_2nd_entry);
jump_to_loader_2nd(loader_2nd_entry);
}
return 0;
}

View File

@ -1 +0,0 @@
cv1800b_sophpi_duo_sd

View File

@ -1 +0,0 @@
cv1800b_wdmb_0008a_spinor

View File

@ -1 +0,0 @@
cv1800b_wdmb_0008a_spinor

Some files were not shown because too many files have changed in this diff Show More