1111import org .bouncycastle .crypto .params .ParametersWithUKM ;
1212import org .bouncycastle .math .ec .ECAlgorithms ;
1313import org .bouncycastle .math .ec .ECPoint ;
14- import org .bouncycastle .util .BigIntegers ;
14+ import org .bouncycastle .util .Arrays ;
1515
1616/**
1717 * GOST VKO key agreement class - RFC 7836 Section 4.3
@@ -28,24 +28,30 @@ public ECVKOAgreement(Digest digest)
2828 this .digest = digest ;
2929 }
3030
31- public void init (
32- CipherParameters key )
31+ public void init (CipherParameters key )
3332 {
3433 ParametersWithUKM p = (ParametersWithUKM )key ;
3534
3635 this .key = (ECPrivateKeyParameters )p .getParameters ();
37- this .ukm = toInteger ( p .getUKM ());
36+ this .ukm = new BigInteger ( 1 , Arrays . reverse ( p .getUKM () ));
3837
3938 CryptoServicesRegistrar .checkConstraints (Utils .getDefaultProperties ("ECVKO" , this .key ));
4039 }
4140
41+ public int getAgreementSize ()
42+ {
43+ return digest .getDigestSize ();
44+ }
45+
46+ /**
47+ * @deprecated Will be removed
48+ */
4249 public int getFieldSize ()
4350 {
4451 return (key .getParameters ().getCurve ().getFieldSize () + 7 ) / 8 ;
4552 }
4653
47- public byte [] calculateAgreement (
48- CipherParameters pubKey )
54+ public byte [] calculateAgreement (CipherParameters pubKey )
4955 {
5056 ECPublicKeyParameters pub = (ECPublicKeyParameters )pubKey ;
5157 ECDomainParameters params = key .getParameters ();
@@ -60,7 +66,7 @@ public byte[] calculateAgreement(
6066 ECPoint pubPoint = ECAlgorithms .cleanPoint (params .getCurve (), pub .getQ ());
6167 if (pubPoint .isInfinity ())
6268 {
63- throw new IllegalStateException ("Infinity is not a valid public key for ECDHC " );
69+ throw new IllegalStateException ("Infinity is not a valid public key for ECVKO " );
6470 }
6571
6672 ECPoint P = pubPoint .multiply (hd ).normalize ();
@@ -70,55 +76,16 @@ public byte[] calculateAgreement(
7076 throw new IllegalStateException ("Infinity is not a valid agreement value for ECVKO" );
7177 }
7278
73- return fromPoint (P );
74- }
75-
76- private static BigInteger toInteger (byte [] ukm )
77- {
78- byte [] v = new byte [ukm .length ];
79-
80- for (int i = 0 ; i != v .length ; i ++)
81- {
82- v [i ] = ukm [ukm .length - i - 1 ];
83- }
84-
85- return new BigInteger (1 , v );
86- }
87-
88- private byte [] fromPoint (ECPoint v )
89- {
90- BigInteger bX = v .getAffineXCoord ().toBigInteger ();
91- BigInteger bY = v .getAffineYCoord ().toBigInteger ();
92-
93- int size ;
94- if (bX .toByteArray ().length > 33 )
95- {
96- size = 64 ;
97- }
98- else
99- {
100- size = 32 ;
101- }
102-
103- byte [] bytes = new byte [2 * size ];
104- byte [] x = BigIntegers .asUnsignedByteArray (size , bX );
105- byte [] y = BigIntegers .asUnsignedByteArray (size , bY );
79+ byte [] encoding = P .getEncoded (false );
80+ int encodingLength = encoding .length ;
81+ int feSize = encodingLength / 2 ;
10682
107- for (int i = 0 ; i != size ; i ++)
108- {
109- bytes [i ] = x [size - i - 1 ];
110- }
111- for (int i = 0 ; i != size ; i ++)
112- {
113- bytes [size + i ] = y [size - i - 1 ];
114- }
115-
116- digest .update (bytes , 0 , bytes .length );
83+ Arrays .reverseInPlace (encoding , encodingLength - feSize * 2 , feSize );
84+ Arrays .reverseInPlace (encoding , encodingLength - feSize , feSize );
11785
11886 byte [] rv = new byte [digest .getDigestSize ()];
119-
87+ digest . update ( encoding , encodingLength - feSize * 2 , feSize * 2 );
12088 digest .doFinal (rv , 0 );
121-
12289 return rv ;
12390 }
12491}
0 commit comments