@@ -149,6 +149,7 @@ void signDigestCore(byte[] ptSignature, byte[] digest, byte[] arraySalt,
149149 final int n = params .getN ();
150150 final int mxlsq = m * lsq ;
151151 final int oxlsq = o * lsq ;
152+ final int vxlsq = v * lsq ;
152153 final int bytesHash = (oxlsq + 1 ) >>> 1 ;
153154 final int bytesSalt = 16 ;
154155
@@ -161,12 +162,11 @@ void signDigestCore(byte[] ptSignature, byte[] digest, byte[] arraySalt,
161162 byte [][][] Right = new byte [alpha ][v ][lsq ];
162163 byte [] leftXTmp = new byte [lsq ];
163164 byte [] rightXtmp = new byte [lsq ];
164- byte [][] XInGF16Matrix = new byte [v ][lsq ];
165165 byte [] FvvGF16Matrix = new byte [lsq ];
166166 byte [] hashInGF16 = new byte [mxlsq ];
167167 byte [] vinegarGf16 = new byte [n * lsq ];
168168 byte [] signedHash = new byte [bytesHash ];
169- byte [] vinegarBytes = new byte [(v * lsq + 1 ) >>> 1 ];
169+ byte [] vinegarBytes = new byte [(vxlsq + 1 ) >>> 1 ];
170170
171171 // Temporary matrices
172172 byte [] gf16mTemp0 = new byte [l ];
@@ -202,18 +202,20 @@ void signDigestCore(byte[] ptSignature, byte[] digest, byte[] arraySalt,
202202 shake .doFinal (vinegarBytes , 0 , vinegarBytes .length );
203203
204204 GF16 .decode (vinegarBytes , vinegarGf16 , vinegarBytes .length << 1 );
205- fill (vinegarGf16 , XInGF16Matrix , vinegarBytes .length << 1 );
206205
207206 for (int i = 0 , ixlsq = 0 ; i < m ; i ++, ixlsq += lsq )
208207 {
209208 Arrays .fill (FvvGF16Matrix , (byte )0 );
210209 // Evaluate vinegar part of central map
211- for (int a = 0 ; a < alpha ; a ++)
210+ for (int a = 0 , miPrime = i ; a < alpha ; a ++, miPrime ++)
212211 {
213- int miPrime = iPrime (i , a );
214- for (int j = 0 ; j < v ; j ++)
212+ if (miPrime >= o )
213+ {
214+ miPrime -= o ;
215+ }
216+ for (int j = 0 , jxlsq = 0 ; j < v ; j ++, jxlsq += lsq )
215217 {
216- GF16Utils .gf16mTranMulMul (XInGF16Matrix [ j ] , Aalpha [i ][a ], Balpha [i ][a ], Qalpha1 [i ][a ],
218+ GF16Utils .gf16mTranMulMul (vinegarGf16 , jxlsq , Aalpha [i ][a ], Balpha [i ][a ], Qalpha1 [i ][a ],
217219 Qalpha2 [i ][a ], gf16mTemp0 , Left [a ][j ], Right [a ][j ], l );
218220 }
219221
@@ -235,15 +237,18 @@ void signDigestCore(byte[] ptSignature, byte[] digest, byte[] arraySalt,
235237 }
236238 }
237239// }
238- // // TODO: think about how this two loops can merge together?
240+ // // TODO: think about why this two loops can merge together?
239241// // Compute the coefficients of Xo and put into Gauss matrix and compute the coefficients of Xo^t and add into Gauss matrix
240242// for (int i = 0, ixlsq = 0; i < m; ++i, ixlsq += lsq)
241243// {
242244 for (int index = 0 , idxlsq = 0 ; index < o ; ++index , idxlsq += lsq )
243245 {
244- for (int a = 0 ; a < alpha ; ++a )
246+ for (int a = 0 , mi_prime = i ; a < alpha ; ++a , ++ mi_prime )
245247 {
246- int mi_prime = iPrime (i , a );
248+ if (mi_prime >= o )
249+ {
250+ mi_prime -= o ;
251+ }
247252 // Initialize Temp to zero
248253 for (int ti = 0 ; ti < lsq ; ++ti )
249254 {
@@ -311,49 +316,43 @@ void signDigestCore(byte[] ptSignature, byte[] digest, byte[] arraySalt,
311316 }
312317
313318 // Copy remaining oil variables
314- System .arraycopy (solution , 0 , vinegarGf16 , v * lsq , oxlsq );
319+ System .arraycopy (solution , 0 , vinegarGf16 , vxlsq , oxlsq );
315320 GF16 .encode (vinegarGf16 , ptSignature , vinegarGf16 .length );
316321
317322 System .arraycopy (arraySalt , 0 , ptSignature , ptSignature .length - bytesSalt , bytesSalt );
318323 }
319324
320325 boolean verifySignatureCore (byte [] digest , byte [] signature , byte [] publicKeySeed , MapGroup1 map1 , byte [][][][] p22 )
321326 {
322- final int bytesHash = (params .getO () * params .getLsq () + 1 ) >>> 1 ;
323- final int bytesSalt = params .getSaltLength ();
324327 final int lsq = params .getLsq ();
328+ final int o = params .getO ();
329+ final int oxlsq = o * lsq ;
330+ final int bytesHash = (oxlsq + 1 ) >>> 1 ;
331+ final int bytesSalt = params .getSaltLength ();
325332 final int m = params .getM ();
326333 final int n = params .getN ();
327- final int o = params .getO ();
328- int bytesSignature = ((n * lsq ) + 1 ) >>> 1 ;
334+ final int nxlsq = n * lsq ;
335+
336+ int bytesSignature = ((nxlsq ) + 1 ) >>> 1 ;
329337
330338 // Step 1: Regenerate signed hash using public key seed, digest and salt
331339 byte [] signedHash = new byte [bytesHash ];
332340 createSignedHash (publicKeySeed , publicKeySeed .length , digest , digest .length ,
333341 signature , bytesSignature , bytesSalt , signedHash , bytesHash );
334342
335343 // Handle odd-length adjustment (if needed)
336- if (((o * lsq ) & 1 ) != 0 )
344+ if (((oxlsq ) & 1 ) != 0 )
337345 {
338346 signedHash [bytesHash - 1 ] &= 0x0F ;
339347 }
340348
341349 // Step 2: Convert signature to GF16 matrices
342- byte [][] signatureGF16Matrix = new byte [n ][lsq ];
343- if ((lsq & 1 ) == 1 )
344- {
345- byte [] decodedSig = new byte [n * lsq ];
346- GF16 .decode (signature , 0 , decodedSig , 0 , decodedSig .length );
347- fill (decodedSig , signatureGF16Matrix , decodedSig .length );
348- }
349- else
350- {
351- MapGroup1 .decodeArray (signature , 0 , signatureGF16Matrix , signature .length );
352- }
350+ byte [] decodedSig = new byte [nxlsq ];
351+ GF16 .decode (signature , 0 , decodedSig , 0 , decodedSig .length );
353352
354353 // Step 3: Evaluate signature using public key
355354 byte [] computedHashBytes = new byte [m * lsq ];
356- evaluation (computedHashBytes , map1 , p22 , signatureGF16Matrix );
355+ evaluation (computedHashBytes , map1 , p22 , decodedSig ); // signatureGF16Matrix);
357356
358357 // Convert computed hash matrix to bytes
359358 byte [] encodedHash = new byte [bytesHash ];
@@ -363,13 +362,14 @@ boolean verifySignatureCore(byte[] digest, byte[] signature, byte[] publicKeySee
363362 return Arrays .areEqual (signedHash , encodedHash );
364363 }
365364
366- private void evaluation (byte [] hashMatrix , MapGroup1 map1 , byte [][][][] p22 , byte [][] signature )
365+ private void evaluation (byte [] hashMatrix , MapGroup1 map1 , byte [][][][] p22 , byte [] signature )
367366 {
368367 final int m = params .getM ();
369368 final int alpha = params .getAlpha ();
370369 final int n = params .getN ();
371370 final int l = params .getL ();
372371 final int lsq = params .getLsq ();
372+ final int o = params .getO ();
373373
374374 byte [][][] Left = new byte [alpha ][n ][lsq ];
375375 byte [][][] Right = new byte [alpha ][n ][lsq ];
@@ -378,21 +378,24 @@ private void evaluation(byte[] hashMatrix, MapGroup1 map1, byte[][][][] p22, byt
378378 // Evaluate Left and Right matrices
379379 for (int mi = 0 , mixlsq = 0 ; mi < m ; mi ++, mixlsq += lsq )
380380 {
381- for (int si = 0 ; si < n ; si ++)
381+ for (int si = 0 , sixlsq = 0 ; si < n ; si ++, sixlsq += lsq )
382382 {
383383 for (int a = 0 ; a < alpha ; a ++)
384384 {
385385 // Left[mi][a][si] = Aalpha * (sig^T * Qalpha1)
386386 // Right[mi][a][si] = (Qalpha2 * sig) * Balpha
387- GF16Utils .gf16mTranMulMul (signature [ si ] , map1 .aAlpha [mi ][a ], map1 .bAlpha [mi ][a ], map1 .qAlpha1 [mi ][a ],
387+ GF16Utils .gf16mTranMulMul (signature , sixlsq , map1 .aAlpha [mi ][a ], map1 .bAlpha [mi ][a ], map1 .qAlpha1 [mi ][a ],
388388 map1 .qAlpha2 [mi ][a ], temp , Left [a ][si ], Right [a ][si ], l );
389389 }
390390 }
391391
392392 // Process P matrices and accumulate results
393- for (int a = 0 ; a < alpha ; a ++)
393+ for (int a = 0 , miPrime = mi ; a < alpha ; a ++, miPrime ++)
394394 {
395- int miPrime = iPrime (mi , a );
395+ if (miPrime >= o )
396+ {
397+ miPrime -= o ;
398+ }
396399 for (int ni = 0 ; ni < n ; ni ++)
397400 {
398401 // sum_t0 = sum(P[miPrime][ni][nj] * Right[mi][a][nj])
@@ -499,23 +502,6 @@ private int performGaussianElimination(byte[][] Gauss, byte[] solution, int size
499502 return 0 ;
500503 }
501504
502- private int iPrime (int mi , int alpha )
503- {
504- // Implement index calculation based on SNOVA specification
505- return (mi + alpha ) % params .getO ();
506- }
507-
508- static void fill (byte [] input , byte [][] output , int len )
509- {
510- int rlt = 0 ;
511- for (int i = 0 ; i < output .length ; ++i )
512- {
513- int tmp = Math .min (output [i ].length , len - rlt );
514- System .arraycopy (input , rlt , output [i ], 0 , tmp );
515- rlt += tmp ;
516- }
517- }
518-
519505 private byte [] getMessageHash (byte [] message )
520506 {
521507 byte [] hash = new byte [shake .getDigestSize ()];
0 commit comments