@@ -52,68 +52,52 @@ public void init(boolean forSigning, CipherParameters param)
5252 }
5353 }
5454
55+ //TODO: make Hash_slh_sign
56+
5557 public byte [] generateSignature (byte [] message )
5658 {
57- // # Input: Message M, private key SK = (SK.seed, SK.prf, PK.seed, PK.root)
58- // # Output: SLH-DSA signature SIG
59- // init
60-
6159 SLHDSAEngine engine = privKey .getParameters ().getEngine ();
6260
6361 engine .init (privKey .pk .seed );
62+ byte [] ctx = privKey .getContext ();
6463
65- // generate randomizer
66- byte [] optRand = new byte [engine .N ];
67- if (random != null )
64+ if (ctx .length > 255 )
6865 {
69- random . nextBytes ( optRand );
66+ throw new RuntimeException ( "Context too long" );
7067 }
71- else
72- {
73- System .arraycopy (privKey .pk .seed , 0 , optRand , 0 , optRand .length );
74- }
75-
76- Fors fors = new Fors (engine );
77- byte [] R = engine .PRF_msg (privKey .sk .prf , optRand , message );
7868
79- // compute message digest and index
80- IndexedDigest idxDigest = engine .H_msg (R , privKey .pk .seed , privKey .pk .root , message );
81- byte [] mHash = idxDigest .digest ;
82- long idx_tree = idxDigest .idx_tree ;
83- int idx_leaf = idxDigest .idx_leaf ;
84- // FORS sign
85- ADRS adrs = new ADRS ();
86- adrs .setType (ADRS .FORS_TREE );
87- adrs .setTreeAddress (idx_tree );
88- adrs .setKeyPairAddress (idx_leaf );
89- SIG_FORS [] sig_fors = fors .sign (mHash , privKey .sk .seed , privKey .pk .seed , adrs );
90- // get FORS public key - spec shows M?
91- adrs = new ADRS ();
92- adrs .setType (ADRS .FORS_TREE );
93- adrs .setTreeAddress (idx_tree );
94- adrs .setKeyPairAddress (idx_leaf );
95- byte [] PK_FORS = fors .pkFromSig (sig_fors , mHash , privKey .pk .seed , adrs );
69+ byte [] ds_message = new byte [1 + 1 + ctx .length + message .length ];
70+ ds_message [0 ] = 0 ;
71+ ds_message [1 ] = (byte )ctx .length ;
72+ System .arraycopy (ctx , 0 , ds_message , 2 , ctx .length );
73+ System .arraycopy (message , 0 , ds_message , 2 + ctx .length , message .length );
9674
97- // sign FORS public key with HT
98- ADRS treeAdrs = new ADRS ();
99- treeAdrs .setType (ADRS .TREE );
75+ // generate randomizer
76+ byte [] optRand = new byte [engine .N ];
77+ return internalGenerateSignature (ds_message , optRand );
78+ }
10079
101- HT ht = new HT (engine , privKey .getSeed (), privKey .getPublicSeed ());
102- byte [] SIG_HT = ht .sign (PK_FORS , idx_tree , idx_leaf );
80+ //TODO: make Hash_slh_verify
10381
104- byte [][] sigComponents = new byte [sig_fors .length + 2 ][];
105- sigComponents [0 ] = R ;
82+ // Equivalent to slh_verify_internal from specs
83+ public boolean verifySignature (byte [] message , byte [] signature )
84+ {
85+ byte [] ctx = pubKey .getContext ();
10686
107- for ( int i = 0 ; i != sig_fors .length ; i ++ )
87+ if ( ctx .length > 255 )
10888 {
109- sigComponents [ 1 + i ] = Arrays . concatenate ( sig_fors [ i ]. sk , Arrays . concatenate ( sig_fors [ i ]. authPath ) );
89+ throw new RuntimeException ( "Context too long" );
11090 }
111- sigComponents [sigComponents .length - 1 ] = SIG_HT ;
11291
113- return Arrays .concatenate (sigComponents );
114- }
92+ byte [] ds_message = new byte [1 + 1 + ctx .length + message .length ];
93+ ds_message [0 ] = 0 ;
94+ ds_message [1 ] = (byte )ctx .length ;
95+ System .arraycopy (ctx , 0 , ds_message , 2 , ctx .length );
96+ System .arraycopy (message , 0 , ds_message , 2 + ctx .length , message .length );
11597
116- public boolean verifySignature (byte [] message , byte [] signature )
98+ return internalVerifySignature (ds_message , signature );
99+ }
100+ public boolean internalVerifySignature (byte [] message , byte [] signature )
117101 {
118102 //# Input: Message M, signature SIG, public key PK
119103 //# Output: Boolean
@@ -124,6 +108,12 @@ public boolean verifySignature(byte[] message, byte[] signature)
124108 engine .init (pubKey .getSeed ());
125109
126110 ADRS adrs = new ADRS ();
111+
112+ if (((1 + engine .K * (1 + engine .A ) + engine .H + engine .D *engine .WOTS_LEN )* engine .N ) != signature .length )
113+ {
114+ return false ;
115+ }
116+
127117 SIG sig = new SIG (engine .N , engine .K , engine .A , engine .D , engine .H_PRIME , engine .WOTS_LEN , signature );
128118
129119 byte [] R = sig .getR ();
@@ -150,5 +140,55 @@ public boolean verifySignature(byte[] message, byte[] signature)
150140 HT ht = new HT (engine , null , pubKey .getSeed ());
151141 return ht .verify (PK_FORS , SIG_HT , pubKey .getSeed (), idx_tree , idx_leaf , pubKey .getRoot ());
152142 }
143+
144+ public byte [] internalGenerateSignature (byte [] message , byte [] optRand )
145+ {
146+ SLHDSAEngine engine = privKey .getParameters ().getEngine ();
147+ engine .init (privKey .pk .seed );
148+
149+ if (optRand == null )
150+ {
151+ optRand = new byte [engine .N ];
152+ System .arraycopy (privKey .pk .seed , 0 , optRand , 0 , optRand .length );
153+ }
154+
155+ Fors fors = new Fors (engine );
156+ byte [] R = engine .PRF_msg (privKey .sk .prf , optRand , message );
157+
158+ IndexedDigest idxDigest = engine .H_msg (R , privKey .pk .seed , privKey .pk .root , message );
159+ byte [] mHash = idxDigest .digest ;
160+ long idx_tree = idxDigest .idx_tree ;
161+ int idx_leaf = idxDigest .idx_leaf ;
162+ // FORS sign
163+ ADRS adrs = new ADRS ();
164+ adrs .setType (ADRS .FORS_TREE );
165+ adrs .setTreeAddress (idx_tree );
166+ adrs .setKeyPairAddress (idx_leaf );
167+ SIG_FORS [] sig_fors = fors .sign (mHash , privKey .sk .seed , privKey .pk .seed , adrs );
168+ // get FORS public key - spec shows M?
169+ adrs = new ADRS ();
170+ adrs .setType (ADRS .FORS_TREE );
171+ adrs .setTreeAddress (idx_tree );
172+ adrs .setKeyPairAddress (idx_leaf );
173+ byte [] PK_FORS = fors .pkFromSig (sig_fors , mHash , privKey .pk .seed , adrs );
174+
175+ // sign FORS public key with HT
176+ ADRS treeAdrs = new ADRS ();
177+ treeAdrs .setType (ADRS .TREE );
178+
179+ HT ht = new HT (engine , privKey .getSeed (), privKey .getPublicSeed ());
180+ byte [] SIG_HT = ht .sign (PK_FORS , idx_tree , idx_leaf );
181+
182+ byte [][] sigComponents = new byte [sig_fors .length + 2 ][];
183+ sigComponents [0 ] = R ;
184+
185+ for (int i = 0 ; i != sig_fors .length ; i ++)
186+ {
187+ sigComponents [1 + i ] = Arrays .concatenate (sig_fors [i ].sk , Arrays .concatenate (sig_fors [i ].authPath ));
188+ }
189+ sigComponents [sigComponents .length - 1 ] = SIG_HT ;
190+
191+ return Arrays .concatenate (sigComponents );
192+ }
153193}
154194
0 commit comments