@@ -52,68 +52,52 @@ public void init(boolean forSigning, CipherParameters param)
52
52
}
53
53
}
54
54
55
+ //TODO: make Hash_slh_sign
56
+
55
57
public byte [] generateSignature (byte [] message )
56
58
{
57
- // # Input: Message M, private key SK = (SK.seed, SK.prf, PK.seed, PK.root)
58
- // # Output: SLH-DSA signature SIG
59
- // init
60
-
61
59
SLHDSAEngine engine = privKey .getParameters ().getEngine ();
62
60
63
61
engine .init (privKey .pk .seed );
62
+ byte [] ctx = privKey .getContext ();
64
63
65
- // generate randomizer
66
- byte [] optRand = new byte [engine .N ];
67
- if (random != null )
64
+ if (ctx .length > 255 )
68
65
{
69
- random . nextBytes ( optRand );
66
+ throw new RuntimeException ( "Context too long" );
70
67
}
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 );
78
68
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 );
96
74
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
+ }
100
79
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
103
81
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 ();
106
86
107
- for ( int i = 0 ; i != sig_fors .length ; i ++ )
87
+ if ( ctx .length > 255 )
108
88
{
109
- sigComponents [ 1 + i ] = Arrays . concatenate ( sig_fors [ i ]. sk , Arrays . concatenate ( sig_fors [ i ]. authPath ) );
89
+ throw new RuntimeException ( "Context too long" );
110
90
}
111
- sigComponents [sigComponents .length - 1 ] = SIG_HT ;
112
91
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 );
115
97
116
- public boolean verifySignature (byte [] message , byte [] signature )
98
+ return internalVerifySignature (ds_message , signature );
99
+ }
100
+ public boolean internalVerifySignature (byte [] message , byte [] signature )
117
101
{
118
102
//# Input: Message M, signature SIG, public key PK
119
103
//# Output: Boolean
@@ -124,6 +108,12 @@ public boolean verifySignature(byte[] message, byte[] signature)
124
108
engine .init (pubKey .getSeed ());
125
109
126
110
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
+
127
117
SIG sig = new SIG (engine .N , engine .K , engine .A , engine .D , engine .H_PRIME , engine .WOTS_LEN , signature );
128
118
129
119
byte [] R = sig .getR ();
@@ -150,5 +140,55 @@ public boolean verifySignature(byte[] message, byte[] signature)
150
140
HT ht = new HT (engine , null , pubKey .getSeed ());
151
141
return ht .verify (PK_FORS , SIG_HT , pubKey .getSeed (), idx_tree , idx_leaf , pubKey .getRoot ());
152
142
}
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
+ }
153
193
}
154
194
0 commit comments