📄 example.c
字号:
/* ===============================================================================
** FILE NAME:
** ---------
** Example.c
**
** DESCRIPTION:
** -----------
** This file contains example code for the CypherMathWin32
** multiprecision unsigned integer math functions.
**
** IMPORTANT: This is a rather long file, because it shows examples of
** every CypherMath function. It is expected that you will single step through
** this file (using your debugger), and verify the results of each calculation
** by examining the affected memory buffers and variables. The expected result
** for each calculation is given in a comment near the call to each CypherMath
** function.
**
** Some basic buffer managment examples are show first, followed by basic math
** operations, then modular math operations, then bit-wise logical operations.
**
**
** REVISION HISTORY:
** ----------------
** 24 November, 1999 - Initial release.
**
** COPYRIGHT NOTICE:
** ----------------
** Copyright (c) 1999, EPS/Solutions. You may use and/or redistribute
** this code as you see fit.
**
** CONTACT INFORMATION:
** -------------------
** EPS/Solutions
** PO Box 862
** Broomall, PA. 19008-0862 (USA)
** Web site: www.cyphercalc.com/math
** Email: support@cyphercalc.com
**
** =============================================================================== */
#include "..\..\..\CypherMathTypesWin32.h"
#include "..\..\..\CypherMathWin32.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Prototypes for test functions. */
void EPS_CypherMathTest(void);
void main(void)
{
/* Start the test code: */
EPS_CypherMathTest();
}
/* ================================================================================
** CypherMath Test Routines
** ================================================================================ */
void EPS_CypherMathTest(void)
{
/* ============================================================================
** Creating Handles to CypherMath Buffers:
** ============================================================================ */
/* Let's start by creating the handles to all of our
** operands, and buffers: */
/* Create some operands to feed the calculations.
** These operands will be 160 (five 32 bit words) bits long.
** Lets define a constant for the operand lengths: */
#define kOPLEN (5)
BUFFERPTR hOp1; /* Handle for operand1 buffer */
BUFFERPTR hOp2; /* Handle for operand2 buffer */
/* Now create a buffer to hold calculation results. It
** should be twice as long as the operands (320 bits or
** ten 32 bit words) to accomodate multiplies: */
#define kRESULTLEN (10)
BUFFERPTR hResult; /* Handle for "calculation results" buffer */
/* For divisions, we'll need a buffer to hold the quotient and
** another to hold the remainder: */
BUFFERPTR hQuotient;
BUFFERPTR hRemainder;
/* We'll need a buffer to hold the modulus for modular calculations: */
BUFFERPTR hModulus;
/* For Montgomery Math calculations, we'll also need the values of
** n0 and n0', so let's make some storage for it now: */
UINT1 n0;
UINT1 n0prime = 0;
/* We'll need storage for the Montgomery Representations of operand1 and operand2.
** Call the buffers operand1prime and operand2prime: */
BUFFERPTR hOp1Prime;
BUFFERPTR hOp2Prime;
/* For exponentiations we'll need an exponent: */
BUFFERPTR hExponent;
/* Later we'll try a "big" exponentiation (512 base and exponent, which is 16 words.
** Allocate the storage for the big base and its Montgomery Image: */
#define kBIGOPLEN (16)
BUFFERPTR hBigBase;
BUFFERPTR hBigBasePrime;
/* Allocate the storage for the big modulus: */
BUFFERPTR hBigModulus;
/* Allocate storage for the result of the big exponentiation: */
BUFFERPTR hBigResult;
/* We'll need storage for the operands for a GCD later: */
BUFFERPTR hR;
BUFFERPTR hRinverse;
BUFFERPTR hN;
BUFFERPTR hNPrime;
BUFFERPTR hD;
/* Create a variable to hold overflow indications, and one
** to hold underflow (borrow) indications: */
UINT1 overflow;
UINT1 borrow;
/* Create a variable to hold the status results of buffer tests
** and comparisons: */
UINDEX2 status;
/* ================================================================
** Start of calls to CypherMath functions:
** ================================================================ */
printf("CypherMath DLL Test. Math Engine version number %d.\n",EPS_GetMathEngineVersion());
puts("Starting Test...");
/* Now that the buffer handles have all been created, let's
** create the buffers themselves for operand 1 and
** operand 2: */
hOp1 = EPS_CreateBuffer(kOPLEN);
hOp2 = EPS_CreateBuffer(kOPLEN);
/* Now create a buffer to hold calculation results. */
hResult = EPS_CreateBuffer(kRESULTLEN);
/* Now let's try some calculations: */
/* ===============================================================
** Addition:
** =============================================================== */
/* Set 1st operand to 12345678 (hex): */
EPS_SetBufferWord(hOp1, 0, EPS_kgFULLWORD, 0x12345678); /* LSW */
/* Now copy operand1 to operand2: */
EPS_CopyBuffer(hOp1, hOp2, kOPLEN);
/* Now overwite operand2 with some other data: */
EPS_SetBufferWord(hOp2, 0, EPS_kgFULLWORD, 0x2FD7C5A0);
/* Now we add the operands. The operation is "result = operand1 + operand2",
** which is 12345678 + 2FD7C5A0. The result should be 420C1C18. */
EPS_Add(hOp1, hOp2, hResult, kOPLEN);
/* Note that since we know the operands are only 32 bits long in this example,
** we can speed things up by specifying a shorter buflen in the call to the
** EPS_Add routine and still get the same result. Of course it would make more
** sense to simply size the operand1 and operand2 buffers smaller, but this
** is just for illustration: */
EPS_Add(hOp1, hOp2, hResult, 1); /* buflen now 1, same result. */
/* Here's a 160 bit addition. First load the operands with 160 bit values.
** Use B49E888D 945A4A20 4D4CC654 0396C2BE D081B582 for operand1 and
** use 0B9C69FD DCD3CA5C 5F9FF641 DF160E65 F3155D2F for operand2. The
** result should be C03AF28B 712E147C ACECBC95 E2ACD124 C39712B1. */
EPS_SetBufferWord(hOp1, 0, EPS_kgFULLWORD, 0xD081B582); /* LSW */
EPS_SetBufferWord(hOp1, 1, EPS_kgFULLWORD, 0x0396C2BE);
EPS_SetBufferWord(hOp1, 2, EPS_kgFULLWORD, 0x4D4CC654);
EPS_SetBufferWord(hOp1, 3, EPS_kgFULLWORD, 0x945A4A20);
EPS_SetBufferWord(hOp1, 4, EPS_kgFULLWORD, 0xB49E888D); /* MSW */
EPS_SetBufferWord(hOp2, 0, EPS_kgFULLWORD, 0xF3155D2F); /* LSW */
EPS_SetBufferWord(hOp2, 1, EPS_kgFULLWORD, 0xDF160E65);
EPS_SetBufferWord(hOp2, 2, EPS_kgFULLWORD, 0x5F9FF641);
EPS_SetBufferWord(hOp2, 3, EPS_kgFULLWORD, 0xDCD3CA5C);
EPS_SetBufferWord(hOp2, 4, EPS_kgFULLWORD, 0x0B9C69FD); /* MSW */
/* This calculation should NOT produce an overflow, but we'll check for one anyway.
** The value of overflow should be zero after the addition: */
overflow = EPS_Add(hOp1, hOp2, hResult, kOPLEN); /* overflow should be 0 */
/* Note that when the addition completes the result buffer has one extra word, where
** the overflow goes (zero in this example). Lets change the MSW of operand2 to
** make the addition overflow: */
EPS_SetBufferWord(hOp2, 4, EPS_kgFULLWORD, 0xFB9C69FD); /* MSW (was 0x0B9C69FD) */
/* This addition WILL overflow, and the value of overflow will be "1" after the
** addition. The sum should be 00000001 B03AF28B 712E147C ACECBC95 E2ACD124 C39712B1.
** Note the "exta" MSW of 00000001. This is the overflow being propagated into the MSW: */
overflow = EPS_Add(hOp1, hOp2, hResult, kOPLEN); /* overflow should be 1 */
/* ===============================================================
** Subtraction:
** =============================================================== */
/* Now lets subtract the operands. Since operand2 is currently greater than operand1,
** the operation (operand2 - operand1) will NOT produce a borrow. The result should
** be 46FDE170 4879803C 12532FED DB7F4BA7 2293A7AD. */
EPS_ClearBuffer(hResult, kRESULTLEN);
borrow = EPS_Subtract(hOp2, hOp1, hResult, kOPLEN); /* borrow should be 0 */
/* Now lets subtract the operands in the other order. Since operand2 is currently
** greater than operand1, the operation (operand1 - operand2) WILL produce a borrow.
** The result should be B9021E8F B7867FC3 EDACD012 2480B458 DD6C5853. */
EPS_ClearBuffer(hResult, kRESULTLEN);
borrow = EPS_Subtract(hOp1, hOp2, hResult, kOPLEN); /* borrow should be 1 */
/* ===============================================================
** Multiplication:
** =============================================================== */
/* Now lets try a multiply. We'll multiply operand1 by operand2. */
/* The product (operand1 * operand2) will be twice as long as the operands. The result should be:
** B185CB46 29379E41 F97B3BCF B1C84F75 49D0FB2E 27ADC023 DA4D49F4 45B183E6 B94504FF B06A8CDE.
** Note that the length parameter we give the multiply function is the length of the operands, not the
** length of the expected result: */
EPS_Multiply(hOp1, hOp2, hResult, kOPLEN);
/* ===============================================================
** Division:
** =============================================================== */
/* We can also divide the operands. For divisions, we'll need an additional buffers to
** hold the quotient and the remainder: */
hQuotient = EPS_CreateBuffer(kOPLEN);
hRemainder = EPS_CreateBuffer(kOPLEN);
/* First, clear the quotient buffer in preparation for division. This is
** required by the EPS_Divide function: */
EPS_ClearBuffer(hQuotient, kOPLEN);
/* Now the division. We'll use operand2 as the dividend (numerator) and operand1 as the
** divisor (denominator): */
status = EPS_Divide(hOp2, hOp1, hQuotient, hRemainder, kOPLEN);
/* You can use the returned status to check for divide-by-zero errors, or bad-dividend
** errors. The resulting quotient should be 00000001.
** The remainder should be 46FDE170 4879803C 12532FED DB7F4BA7 2293A7AD. */
/* ===============================================================
** Squaring:
** =============================================================== */
/* Now let's try the EPS_Square function. This calculates square of A,
** where A = 0xB48F48B0 4F2381EF 5CD0FC25 8CDB8A84 721C09A9.
** Result should be: 7F59CE6A 38E5FE54 A64FD082 31E76309 596768A2
** B3919B70 CB3596C6 801C78EF 795725F4 A1555191 */
EPS_SetBufferWord(hOp1, 0, EPS_kgFULLWORD, 0x721C09A9);
EPS_SetBufferWord(hOp1, 1, EPS_kgFULLWORD, 0x8CDB8A84);
EPS_SetBufferWord(hOp1, 2, EPS_kgFULLWORD, 0x5CD0FC25);
EPS_SetBufferWord(hOp1, 3, EPS_kgFULLWORD, 0x4F2381EF);
EPS_SetBufferWord(hOp1, 4, EPS_kgFULLWORD, 0xB48F48B0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -