#
source:
trunk/third/moira/util/rsaref/r_dh.c
@
23095

Revision 23095, 4.8 KB checked in by ghudson, 16 years ago (diff) |
---|

Rev | Line | |
---|---|---|

[23095] | 1 | /* R_DH.C - Diffie-Hellman routines for RSAREF |

2 | */ | |

3 | ||

4 | /* Copyright (C) RSA Laboratories, a division of RSA Data Security, | |

5 | Inc., created 1993. All rights reserved. | |

6 | */ | |

7 | ||

8 | #include "global.h" | |

9 | #include "rsaref.h" | |

10 | #include "r_random.h" | |

11 | #include "nn.h" | |

12 | #include "prime.h" | |

13 | ||

14 | /* Generates Diffie-Hellman parameters. | |

15 | */ | |

16 | int R_GenerateDHParams (params, primeBits, subPrimeBits, randomStruct) | |

17 | R_DH_PARAMS *params; /* new Diffie-Hellman parameters */ | |

18 | unsigned int primeBits; /* length of prime in bits */ | |

19 | unsigned int subPrimeBits; /* length of subprime in bits */ | |

20 | R_RANDOM_STRUCT *randomStruct; /* random structure */ | |

21 | { | |

22 | int status; | |

23 | NN_DIGIT g[MAX_NN_DIGITS], p[MAX_NN_DIGITS], q[MAX_NN_DIGITS], | |

24 | t[MAX_NN_DIGITS], u[MAX_NN_DIGITS], v[MAX_NN_DIGITS]; | |

25 | unsigned int pDigits; | |

26 | ||

27 | pDigits = (primeBits + NN_DIGIT_BITS - 1) / NN_DIGIT_BITS; | |

28 | ||

29 | /* Generate subprime q between 2^(subPrimeBits-1) and | |

30 | 2^subPrimeBits-1, searching in steps of 2. | |

31 | */ | |

32 | NN_Assign2Exp (t, subPrimeBits-1, pDigits); | |

33 | NN_Assign (u, t, pDigits); | |

34 | NN_ASSIGN_DIGIT (v, 1, pDigits); | |

35 | NN_Sub (v, t, v, pDigits); | |

36 | NN_Add (u, u, v, pDigits); | |

37 | NN_ASSIGN_DIGIT (v, 2, pDigits); | |

38 | if (status = GeneratePrime (q, t, u, v, pDigits, randomStruct)) | |

39 | return (status); | |

40 | ||

41 | /* Generate prime p between 2^(primeBits-1) and 2^primeBits-1, | |

42 | searching in steps of 2*q. | |

43 | */ | |

44 | NN_Assign2Exp (t, primeBits-1, pDigits); | |

45 | NN_Assign (u, t, pDigits); | |

46 | NN_ASSIGN_DIGIT (v, 1, pDigits); | |

47 | NN_Sub (v, t, v, pDigits); | |

48 | NN_Add (u, u, v, pDigits); | |

49 | NN_LShift (v, q, 1, pDigits); | |

50 | if (status = GeneratePrime (p, t, u, v, pDigits, randomStruct)) | |

51 | return (status); | |

52 | ||

53 | /* Generate generator g for subgroup as 2^((p-1)/q) mod p. | |

54 | */ | |

55 | NN_ASSIGN_DIGIT (g, 2, pDigits); | |

56 | NN_Div (t, u, p, pDigits, q, pDigits); | |

57 | NN_ModExp (g, g, t, pDigits, p, pDigits); | |

58 | ||

59 | params->generatorLen = params->primeLen = DH_PRIME_LEN (primeBits); | |

60 | NN_Encode (params->prime, params->primeLen, p, pDigits); | |

61 | NN_Encode (params->generator, params->generatorLen, g, pDigits); | |

62 | ||

63 | return (0); | |

64 | } | |

65 | ||

66 | /* Sets up Diffie-Hellman key agreement. Public value has same length | |

67 | as prime. | |

68 | */ | |

69 | int R_SetupDHAgreement | |

70 | (publicValue, privateValue, privateValueLen, params, randomStruct) | |

71 | unsigned char *publicValue; /* new public value */ | |

72 | unsigned char *privateValue; /* new private value */ | |

73 | unsigned int privateValueLen; /* length of private value */ | |

74 | R_DH_PARAMS *params; /* Diffie-Hellman parameters */ | |

75 | R_RANDOM_STRUCT *randomStruct; /* random structure */ | |

76 | { | |

77 | int status; | |

78 | NN_DIGIT g[MAX_NN_DIGITS], p[MAX_NN_DIGITS], x[MAX_NN_DIGITS], | |

79 | y[MAX_NN_DIGITS]; | |

80 | unsigned int pDigits, xDigits; | |

81 | ||

82 | NN_Decode (p, MAX_NN_DIGITS, params->prime, params->primeLen); | |

83 | pDigits = NN_Digits (p, MAX_NN_DIGITS); | |

84 | NN_Decode (g, pDigits, params->generator, params->generatorLen); | |

85 | ||

86 | /* Generate private value. | |

87 | */ | |

88 | if (status = R_GenerateBytes (privateValue, privateValueLen, randomStruct)) | |

89 | return (status); | |

90 | NN_Decode (x, pDigits, privateValue, privateValueLen); | |

91 | xDigits = NN_Digits (x, pDigits); | |

92 | ||

93 | /* Compute y = g^x mod p. | |

94 | */ | |

95 | NN_ModExp (y, g, x, xDigits, p, pDigits); | |

96 | ||

97 | NN_Encode (publicValue, params->primeLen, y, pDigits); | |

98 | ||

99 | /* Zeroize sensitive information. | |

100 | */ | |

101 | R_memset ((POINTER)x, 0, sizeof (x)); | |

102 | ||

103 | return (0); | |

104 | } | |

105 | ||

106 | /* Computes agreed key from the other party's public value, a private | |

107 | value, and Diffie-Hellman parameters. Other public value and | |

108 | agreed-upon key have same length as prime. | |

109 | ||

110 | Requires otherPublicValue < prime. | |

111 | */ | |

112 | int R_ComputeDHAgreedKey | |

113 | (agreedKey, otherPublicValue, privateValue, privateValueLen, params) | |

114 | unsigned char *agreedKey; /* new agreed key */ | |

115 | unsigned char *otherPublicValue; /* other's public value */ | |

116 | unsigned char *privateValue; /* private value */ | |

117 | unsigned int privateValueLen; /* length of private value */ | |

118 | R_DH_PARAMS *params; /* Diffie-Hellman parameters */ | |

119 | { | |

120 | NN_DIGIT p[MAX_NN_DIGITS], x[MAX_NN_DIGITS], y[MAX_NN_DIGITS], | |

121 | z[MAX_NN_DIGITS]; | |

122 | unsigned int pDigits, xDigits; | |

123 | ||

124 | NN_Decode (p, MAX_NN_DIGITS, params->prime, params->primeLen); | |

125 | pDigits = NN_Digits (p, MAX_NN_DIGITS); | |

126 | NN_Decode (x, pDigits, privateValue, privateValueLen); | |

127 | xDigits = NN_Digits (x, pDigits); | |

128 | NN_Decode (y, pDigits, otherPublicValue, params->primeLen); | |

129 | ||

130 | if (NN_Cmp (y, p, pDigits) >= 0) | |

131 | return (RE_DATA); | |

132 | ||

133 | /* Compute z = y^x mod p. | |

134 | */ | |

135 | NN_ModExp (z, y, x, xDigits, p, pDigits); | |

136 | ||

137 | NN_Encode (agreedKey, params->primeLen, z, pDigits); | |

138 | ||

139 | /* Zeroize sensitive information. | |

140 | */ | |

141 | R_memset ((POINTER)x, 0, sizeof (x)); | |

142 | R_memset ((POINTER)z, 0, sizeof (z)); | |

143 | ||

144 | return (0); | |

145 | } |

**Note:**See TracBrowser for help on using the repository browser.