22
33import java .security .SecureRandom ;
44
5+ import org .bouncycastle .crypto .Digest ;
56import org .bouncycastle .crypto .digests .SHAKEDigest ;
67import org .bouncycastle .util .Arrays ;
78
@@ -244,24 +245,28 @@ else if (this.DilithiumGamma1 == (1 << 19))
244245 }
245246 }
246247
247- public byte [][] generateKeyPair ()
248+ //Internal functions are deterministic. No randomness is sampled inside them
249+ public byte [][] generateKeyPairInternal (byte [] seed )
248250 {
249- byte [] seedBuf = new byte [SeedBytes ];
250251 byte [] buf = new byte [2 * SeedBytes + CrhBytes ];
251252 byte [] tr = new byte [TrBytes ];
252253
253254 byte [] rho = new byte [SeedBytes ],
254- rhoPrime = new byte [CrhBytes ],
255- key = new byte [SeedBytes ];
255+ rhoPrime = new byte [CrhBytes ],
256+ key = new byte [SeedBytes ];
256257
257258 PolyVecMatrix aMatrix = new PolyVecMatrix (this );
258259
259260 PolyVecL s1 = new PolyVecL (this ), s1hat ;
260261 PolyVecK s2 = new PolyVecK (this ), t1 = new PolyVecK (this ), t0 = new PolyVecK (this );
261262
262- random .nextBytes (seedBuf );
263263
264- shake256Digest .update (seedBuf , 0 , SeedBytes );
264+
265+ shake256Digest .update (seed , 0 , SeedBytes );
266+
267+ //Domain separation
268+ shake256Digest .update ((byte )DilithiumK );
269+ shake256Digest .update ((byte )DilithiumL );
265270
266271 shake256Digest .doFinal (buf , 0 , 2 * SeedBytes + CrhBytes );
267272 // System.out.print("buf = ");
@@ -315,11 +320,11 @@ public byte[][] generateKeyPair()
315320 shake256Digest .doFinal (tr , 0 , TrBytes );
316321
317322 byte [][] sk = Packing .packSecretKey (rho , tr , key , t0 , s1 , s2 , this );
318-
323+
319324 return new byte [][]{ sk [0 ], sk [1 ], sk [2 ], sk [3 ], sk [4 ], sk [5 ], encT1 };
320325 }
321326
322- public byte [] signSignature (byte [] msg , int msglen , byte [] rho , byte [] key , byte [] tr , byte [] t0Enc , byte [] s1Enc , byte [] s2Enc )
327+ public byte [] signSignatureInternal (byte [] msg , int msglen , byte [] rho , byte [] key , byte [] tr , byte [] t0Enc , byte [] s1Enc , byte [] s2Enc , byte [] rnd )
323328 {
324329 int n ;
325330 byte [] outSig = new byte [CryptoBytes + msglen ];
@@ -336,11 +341,7 @@ public byte[] signSignature(byte[] msg, int msglen, byte[] rho, byte[] key, byte
336341 this .shake256Digest .update (msg , 0 , msglen );
337342 this .shake256Digest .doFinal (mu , 0 , CrhBytes );
338343
339- byte [] rnd = new byte [RndBytes ];
340- if (random != null )
341- {
342- random .nextBytes (rnd );
343- }
344+
344345
345346 byte [] keyMu = Arrays .copyOf (key , SeedBytes + RndBytes + CrhBytes );
346347 System .arraycopy (rnd , 0 , keyMu , SeedBytes , RndBytes );
@@ -424,17 +425,12 @@ public byte[] signSignature(byte[] msg, int msglen, byte[] rho, byte[] key, byte
424425 return null ;
425426 }
426427
427- public byte [] sign (byte [] msg , int mlen , byte [] rho , byte [] key , byte [] tr , byte [] t0 , byte [] s1 , byte [] s2 )
428- {
429- return signSignature (msg , mlen , rho , key , tr , t0 , s1 , s2 );
430- }
431-
432- public boolean signVerify (byte [] sig , int siglen , byte [] msg , int msglen , byte [] rho , byte [] encT1 )
428+ public boolean signVerifyInternal (byte [] sig , int siglen , byte [] msg , int msglen , byte [] rho , byte [] encT1 )
433429 {
434430 byte [] buf ,
435- mu = new byte [CrhBytes ],
436- c ,
437- c2 = new byte [DilithiumCTilde ];
431+ mu = new byte [CrhBytes ],
432+ c ,
433+ c2 = new byte [DilithiumCTilde ];
438434 Poly cp = new Poly (this );
439435 PolyVecMatrix aMatrix = new PolyVecMatrix (this );
440436 PolyVecL z = new PolyVecL (this );
@@ -540,8 +536,50 @@ public boolean signVerify(byte[] sig, int siglen, byte[] msg, int msglen, byte[]
540536 return Arrays .constantTimeAreEqual (c , c2 );
541537 }
542538
539+
540+
541+ public byte [][] generateKeyPair ()
542+ {
543+ byte [] seedBuf = new byte [SeedBytes ];
544+ random .nextBytes (seedBuf );
545+ return generateKeyPairInternal (seedBuf );
546+
547+ }
548+
549+ public byte [] signSignature (byte [] msg , int msglen , byte [] rho , byte [] key , byte [] tr , byte [] t0Enc , byte [] s1Enc , byte [] s2Enc )
550+ {
551+ byte [] rnd = new byte [RndBytes ];
552+ if (random != null )
553+ {
554+ random .nextBytes (rnd );
555+ }
556+ return signSignatureInternal (msg , msglen , rho , key , tr , t0Enc , s1Enc , s2Enc , rnd );
557+ }
558+
559+ public byte [] sign (byte [] msg , int mlen , byte [] rho , byte [] key , byte [] tr , byte [] t0 , byte [] s1 , byte [] s2 )
560+ {
561+ return signSignature (msg , mlen , rho , key , tr , t0 , s1 , s2 );
562+ }
563+
564+ public boolean signVerify (byte [] sig , int siglen , byte [] msg , int msglen , byte [] rho , byte [] encT1 )
565+ {
566+ //TODO: add domain separation
567+ // M' <- BytesToBits( IntegerToBytes(0, 1) || IntegerToBytes(|ctx|, 1) || ctx ) || M
568+ return signVerifyInternal (sig , siglen , msg , msglen , rho , encT1 );
569+ }
570+
543571 public boolean signOpen (byte [] msg , byte [] signedMsg , int signedMsglen , byte [] rho , byte [] t1 )
544572 {
573+ //TODO: add domain separation
574+ // M' <- BytesToBits( IntegerToBytes(0, 1) || IntegerToBytes(|ctx|, 1) || ctx ) || M
545575 return signVerify (signedMsg , signedMsglen , msg , msg .length , rho , t1 );
546576 }
577+
578+ // HashML-DSA
579+ //TODO: Generate a "pre-hash" ML-DSA signature
580+ // public byte[] hashSign(byte[] sk, byte[] message, byte[] ctx, Digest ph) {}
581+ //TODO: Verify a pre-hash HashML-DSA signature
582+ // public boolean hashVerify(byte[] pk, byte[] message, byte[] sig) {}
583+
584+
547585}
0 commit comments