📄 diffiehellman.c
字号:
/* ===============================================================================
** FILE NAME:
** ---------
** DiffieHellman.c
**
** DESCRIPTION:
** -----------
** This file contains example code for the CypherMathWin32
** multiprecision unsigned integer math functions. It shows a simple
** example of a Diffie-Hellman key exchange, using CypherMathWin32.
**
** You can 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 the corresponding CypherMath function.
**
** This simulation uses the Montgomery Method for modular exponetiation.
**
** NOTE: This sample simulates "both ends" of the exchange. That is,
** calculations are shown for both User1 and User2. In reality, only one
** half of this simulation would need to be implemented in a product.
**
**
**
** 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>
/* Prototype for test function: */
void EPS_DiffieHellman(void);
void main(void)
{
/* Start the test code: */
EPS_DiffieHellman();
}
void EPS_DiffieHellman(void)
/* ================================================================================
** CypherMath Diffie-Hellman key exchange implementaion
** ================================================================================
**
** This CypherMath sample code shows an example of a 160-bit
** Diffie-Hellman exchange.
**
** Background
** ----------
** The "Diffie-Hellman Method For Key Agreement" allows two users
** to create and share a secret key.
**
** First the users must have the "Diffie-Hellman parameters". A prime
** number, P (larger than 2) and base, G, an integer that is smaller
** than P.
**
** The users each secretly generate a private number (called X for
** User 1 and Y for User 2), which is less than P-1.
**
** The users next generate the public Diffie-Hellman components (called
** Public1 for User 1 and Public2 for User 2). They are created
** with the functions:
**
** Public1 = G^X mod P (for User 1)
** Public2 = G^Y mod P (for User 2)
**
** The two users now exchange the public components (Public1 and
** Public2), and the exchanged numbers are converted into a secret
** session key (called K1 for User 1 and K2 for User 2) using:
**
** K1 = Public2^X mod P (for User 1)
** K2 = Public1^Y mod P (for User 2)
**
** Note that K1 and K2 should be equal, i.e., both users now have the
** same session key:
**
** K1 = (Public2^X mod P) = (Public1^Y mod P) = K2
**
** ======================================================================= */
{
/* Create handles to all the buffers we'll need: */
BUFFERPTR hP; /* Handle to P's buffer */
BUFFERPTR hG; /* Handle to G's buffer */
BUFFERPTR hX; /* Handle to X's buffer (User1's random component) */
BUFFERPTR hY; /* Handle to Y's buffer (User2's random component) */
BUFFERPTR hPublic1; /* Handle to Public1's buffer (User1's public component) */
BUFFERPTR hPublic2; /* Handle to Public2's buffer (User2's public component) */
BUFFERPTR hK1; /* Handle to K1's buffer (User1's calculated session key) */
BUFFERPTR hK2; /* Handle to K2's buffer (User1's calculated session key) */
UINT1 n0; /* Will hold least significant word of modulus */
UINT1 n0prime = 0; /* Will hold Mongomery paramter for n0. */
/* Tell the console that the test has begun: */
printf("CypherMath Diffie-Hellman Simulation. Math Engine version number %d.\n",EPS_GetMathEngineVersion());
puts("Starting Test...");
/* Now create the buffers themselves. These buffers will be 160 bits (five
** 32-bit words) long. Lets define a constant for the operand lengths: */
#define kOPLEN (5)
hP = EPS_CreateBuffer(kOPLEN);
hG = EPS_CreateBuffer(kOPLEN);
hX = EPS_CreateBuffer(kOPLEN);
hY = EPS_CreateBuffer(kOPLEN);
hPublic1 = EPS_CreateBuffer(kOPLEN);
hPublic2 = EPS_CreateBuffer(kOPLEN);
hK1 = EPS_CreateBuffer(kOPLEN);
hK2 = EPS_CreateBuffer(kOPLEN);
/* =================================================================
** Initialize the Diffie-Hellman parameters:
** ================================================================= */
/* Load the Diffie-Hellman "P" parameter. This is the modulus that
** will be used in later modular exponentiations: */
/* A 160-bit prime number, P:
** 0xB20DB0B1 01DF0C66 24FC1392 BA55F77D 577481E5 */
EPS_SetBufferWord(hP, 0, EPS_kgFULLWORD, 0x577481E5); /* LSW */
EPS_SetBufferWord(hP, 1, EPS_kgFULLWORD, 0xBA55F77D);
EPS_SetBufferWord(hP, 2, EPS_kgFULLWORD, 0x24FC1392);
EPS_SetBufferWord(hP, 3, EPS_kgFULLWORD, 0x01DF0C66);
EPS_SetBufferWord(hP, 4, EPS_kgFULLWORD, 0xB20DB0B1); /* MSW */
/* Load the Diffie-Hellman "G" parameter. This is the base that
** will be used in later modular exponentiations: */
/* A base, G, that is smaller than P:
** 0x0B9C69FD DCD3CA5C 5F9FF641 DF160E65 F3155D2F */
EPS_SetBufferWord(hG, 0, EPS_kgFULLWORD, 0xF3155D2F); /* LSW */
EPS_SetBufferWord(hG, 1, EPS_kgFULLWORD, 0xDF160E65);
EPS_SetBufferWord(hG, 2, EPS_kgFULLWORD, 0x5F9FF641);
EPS_SetBufferWord(hG, 3, EPS_kgFULLWORD, 0xDCD3CA5C);
EPS_SetBufferWord(hG, 4, EPS_kgFULLWORD, 0x0B9C69FD); /* MSW */
/* For the subsequent modular calculations, we'll need the value of n0', so
** let's calculate it now. We'll need the LSW of the modulus P, n0: */
n0 = EPS_GetBufferWord(hP, 0, EPS_kgFULLWORD);
EPS_FindN0Prime(n0, &n0prime); /* n0' should be 0x977B2C13 for this modulus */
/* Now let's get G', the Montgomery Representation of the base G, since all subsequent
** exponentiations will use this, instead of G itself. We'll store it back in G: */
EPS_MontRep(hG, hG, hP, kOPLEN);
/* G' = 0x47AB1FB4 2AAEC89C BF3BF440 A3ED309E FCB2F167 */
/* =========================================================================
** The users generate their random components:
** ========================================================================= */
/* User 1 picks a private random number, X, less than P-1:
** X = 0x69FDDCD3 CA5C5F9F F641DF16 0E65F315 5D2F865D */
EPS_SetBufferWord(hX, 0, EPS_kgFULLWORD, 0x5D2F865D); /* LSW */
EPS_SetBufferWord(hX, 1, EPS_kgFULLWORD, 0x0E65F315);
EPS_SetBufferWord(hX, 2, EPS_kgFULLWORD, 0xF641DF16);
EPS_SetBufferWord(hX, 3, EPS_kgFULLWORD, 0xCA5C5F9F);
EPS_SetBufferWord(hX, 4, EPS_kgFULLWORD, 0x69FDDCD3); /* MSW */
/* User 2 picks a private random number, Y, less than P-1:
** Y = 0x0DB297AA 77FC4C54 9F68A5D6 43874782 D46DD318 */
EPS_SetBufferWord(hY, 0, EPS_kgFULLWORD, 0xD46DD318); /* LSW */
EPS_SetBufferWord(hY, 1, EPS_kgFULLWORD, 0x43874782);
EPS_SetBufferWord(hY, 2, EPS_kgFULLWORD, 0x9F68A5D6);
EPS_SetBufferWord(hY, 3, EPS_kgFULLWORD, 0x77FC4C54);
EPS_SetBufferWord(hY, 4, EPS_kgFULLWORD, 0x0DB297AA); /* MSW */
/* =========================================================================
** The users generate their public components:
** ========================================================================= */
/* User 1 generates his public component, Public1 = G^X mod P: */
EPS_MontExp(hG, hX, hPublic1, hP, n0prime, kOPLEN, kOPLEN);
/* Convert result from Montgomery Representation to Normal Representaion: */
EPS_NormalRep(hPublic1, hPublic1, hP, n0prime, kOPLEN);
/* Public1 = 0x3666541A 1B62E180 02BB3B66 C63FF48D 430394A0 */
/* User 2 generates his public component, Public2 = G^Y mod P: */
EPS_MontExp(hG, hY, hPublic2, hP, n0prime, kOPLEN, kOPLEN);
/* Convert result from Montgomery Representation to Normal Representaion: */
EPS_NormalRep(hPublic2, hPublic2, hP, n0prime, kOPLEN);
/* Public2 = 0x9B464532 2ED78E5C ED0A380E 787A9390 891635C9 */
/* =============================================================
** The Users Exchange Public Components:
**
** User 1 sends his Public1 to User 2, and User 2 sends his
** Public2 to User 1.
** ============================================================= */
/* =============================================================
** The Users generate the session key:
** ============================================================= */
/* User 1 generates his private session key, K1 = Public2^X mod P.
** He'll need the Montgomery Representation of hPublic2 for
** this calculation: */
EPS_MontRep(hPublic2, hPublic2, hP, kOPLEN);
/* Now the exponentiation: */
EPS_MontExp(hPublic2, hX, hK1, hP, n0prime, kOPLEN, kOPLEN);
/* Convert result from Montgomery Representation to Normal Representation: */
EPS_NormalRep(hK1, hK1, hP, n0prime, kOPLEN);
/* K1 = 0x4CFC3B2F EBBA0DAE 8DCFF198 29B9B801 8DF81CB7 */
/* User 2 generates his private session key, K2 = Public1^Y mod P:
** He'll need the Montgomery Representation of hPublic1 for
** this calculation: */
EPS_MontRep(hPublic1, hPublic1, hP, kOPLEN);
/* Now the exponentiation: */
EPS_MontExp(hPublic1, hY, hK2, hP, n0prime, kOPLEN, kOPLEN);
/* Convert result from Montgomery Representation to Normal Representation: */
EPS_NormalRep(hK2, hK2, hP, n0prime, kOPLEN);
/* K2 = 0x4CFC3B2F EBBA0DAE 8DCFF198 29B9B801 8DF81CB7 */
/* If all went well, User 1 and User 2 should now have the
** same session key. That is, K1 = K2. */
/* ===================================================================
** Release the buffers:
** =================================================================== */
EPS_CloseBuffer(hP);
EPS_CloseBuffer(hG);
EPS_CloseBuffer(hX);
EPS_CloseBuffer(hY);
EPS_CloseBuffer(hPublic1);
EPS_CloseBuffer(hPublic2);
EPS_CloseBuffer(hK1);
EPS_CloseBuffer(hK2);
/* Test Done! */
puts("Test Completed.");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -