@@ -67,6 +67,9 @@ public KeyAgreementImpl(byte algorithm) {
67
67
case ALG_DH_PLAIN :
68
68
engine = new DHBasicAgreement ();
69
69
break ;
70
+ case ALG_EC_PACE_GM :
71
+ engine = new ECGMAgreement ();
72
+ break ;
70
73
default :
71
74
CryptoException .throwIt (CryptoException .NO_SUCH_ALGORITHM );
72
75
break ;
@@ -112,7 +115,7 @@ public short generateSecret(byte[] publicData,
112
115
byte [] num = engine .calculateAgreement (ecp ).toByteArray ();
113
116
114
117
byte [] result ;
115
- if (algorithm != ALG_EC_SVDP_DH_PLAIN_XY ) {
118
+ if (algorithm != ALG_EC_SVDP_DH_PLAIN_XY && algorithm != ALG_EC_PACE_GM ) {
116
119
// truncate/zero-pad to field size as per the spec:
117
120
int fieldSize = ((ECPrivateKeyImpl ) privateKey ).getDomainParameters ().getCurve ().getFieldSize ();
118
121
result = new byte [(fieldSize + 7 ) / 8 ];
@@ -139,7 +142,8 @@ public short generateSecret(byte[] publicData,
139
142
return (short ) hashResult .length ;
140
143
case ALG_EC_SVDP_DHC_PLAIN : // no break
141
144
case ALG_EC_SVDP_DH_PLAIN : // no break
142
- case ALG_EC_SVDP_DH_PLAIN_XY :
145
+ case ALG_EC_SVDP_DH_PLAIN_XY : // no break
146
+ case ALG_EC_PACE_GM :
143
147
// plain output
144
148
Util .arrayCopyNonAtomic (result , (short ) 0 , secret , secretOffset , (short ) result .length );
145
149
return (short ) result .length ;
@@ -168,12 +172,8 @@ public void init(CipherParameters privateKey) {
168
172
this .key = (ECPrivateKeyParameters )privateKey ;
169
173
}
170
174
171
- /**
172
- * return the field size for the agreement algorithm in bytes.
173
- */
174
- @ Override
175
175
public int getFieldSize () {
176
- throw new UnsupportedOperationException ( "Not supported yet." ) ;
176
+ return ( this . key . getParameters (). getCurve (). getFieldSize () + 7 ) / 8 ;
177
177
}
178
178
179
179
public BigInteger calculateAgreement (CipherParameters publicKey ) {
@@ -182,4 +182,30 @@ public BigInteger calculateAgreement(CipherParameters publicKey) {
182
182
return new BigInteger (1 , result .getEncoded (false ));
183
183
}
184
184
}
185
+
186
+ /**
187
+ * BouncyCastle doesn't offer KeyAgreement analogous to <code>ALG_EC_PACE_GM</code>.
188
+ * So do it here instead and squeeze the resulting point through byte encoding
189
+ * in a BigInteger.
190
+ */
191
+ static class ECGMAgreement implements BasicAgreement {
192
+ private ECPrivateKeyParameters key ;
193
+
194
+ public ECGMAgreement () {
195
+ }
196
+
197
+ public void init (CipherParameters privateKey ) {
198
+ this .key = (ECPrivateKeyParameters ) privateKey ;
199
+ }
200
+
201
+ public int getFieldSize () {
202
+ return (this .key .getParameters ().getCurve ().getFieldSize () + 7 ) / 8 ;
203
+ }
204
+
205
+ public BigInteger calculateAgreement (CipherParameters publicKey ) {
206
+ ECPublicKeyParameters pub = (ECPublicKeyParameters ) publicKey ;
207
+ ECPoint result = this .key .getParameters ().getG ().multiply (this .key .getD ()).add (pub .getQ ());
208
+ return new BigInteger (1 , result .getEncoded (false ));
209
+ }
210
+ }
185
211
}
0 commit comments