@@ -47,15 +47,34 @@ func canUseKDSA(c curveID) (functionCode uint64, blockSize int, ok bool) {
47
47
case p384 :
48
48
return 2 , 48 , true
49
49
case p521 :
50
+ // Note that the block size doesn't match the field size for P-521.
50
51
return 3 , 80 , true
51
52
}
52
53
return 0 , 0 , false // A mismatch
53
54
}
54
55
55
- func hashToBytes [P Point [P ]](c * Curve [P ], dst , hash []byte ) {
56
+ func hashToBytes [P Point [P ]](c * Curve [P ], hash []byte ) [] byte {
56
57
e := bigmod .NewNat ()
57
58
hashToNat (c , e , hash )
58
- copy (dst , e .Bytes (c .N ))
59
+ return e .Bytes (c .N )
60
+ }
61
+
62
+ func appendBlock (p []byte , blocksize int , b []byte ) []byte {
63
+ if len (b ) > blocksize {
64
+ panic ("ecdsa: internal error: appendBlock input larger than block" )
65
+ }
66
+ padding := blocksize - len (b )
67
+ p = append (p , make ([]byte , padding )... )
68
+ return append (p , b ... )
69
+ }
70
+
71
+ func trimBlock (p []byte , size int ) ([]byte , error ) {
72
+ for _ , b := range p [:len (p )- size ] {
73
+ if b != 0 {
74
+ return nil , errors .New ("ecdsa: internal error: KDSA produced invalid signature" )
75
+ }
76
+ }
77
+ return p [len (p )- size :], nil
59
78
}
60
79
61
80
func sign [P Point [P ]](c * Curve [P ], priv * PrivateKey , drbg * hmacDRBG , hash []byte ) (* Signature , error ) {
@@ -95,17 +114,27 @@ func sign[P Point[P]](c *Curve[P], priv *PrivateKey, drbg *hmacDRBG, hash []byte
95
114
96
115
// Copy content into the parameter block. In the sign case,
97
116
// we copy hashed message, private key and random number into
98
- // the parameter block.
99
- hashToBytes (c , params [2 * blockSize :3 * blockSize ], hash )
100
- copy (params [3 * blockSize + blockSize - len (priv .d ):], priv .d )
101
- copy (params [4 * blockSize :5 * blockSize ], k .Bytes (c .N ))
117
+ // the parameter block. We skip the signature slots.
118
+ p := params [:2 * blockSize ]
119
+ p = appendBlock (p , blockSize , hashToBytes (c , hash ))
120
+ p = appendBlock (p , blockSize , priv .d )
121
+ p = appendBlock (p , blockSize , k .Bytes (c .N ))
102
122
// Convert verify function code into a sign function code by adding 8.
103
123
// We also need to set the 'deterministic' bit in the function code, by
104
124
// adding 128, in order to stop the instruction using its own random number
105
125
// generator in addition to the random number we supply.
106
126
switch kdsa (functionCode + 136 , & params ) {
107
127
case 0 : // success
108
- return & Signature {R : params [:blockSize ], S : params [blockSize : 2 * blockSize ]}, nil
128
+ elementSize := (c .N .BitLen () + 7 ) / 8
129
+ r , err := trimBlock (params [:blockSize ], elementSize )
130
+ if err != nil {
131
+ return nil , err
132
+ }
133
+ s , err := trimBlock (params [blockSize :2 * blockSize ], elementSize )
134
+ if err != nil {
135
+ return nil , err
136
+ }
137
+ return & Signature {R : r , S : s }, nil
109
138
case 1 : // error
110
139
return nil , errors .New ("zero parameter" )
111
140
case 2 : // retry
@@ -149,10 +178,12 @@ func verify[P Point[P]](c *Curve[P], pub *PublicKey, hash []byte, sig *Signature
149
178
// Copy content into the parameter block. In the verify case,
150
179
// we copy signature (r), signature(s), hashed message, public key x component,
151
180
// and public key y component into the parameter block.
152
- copy (params [0 * blockSize + blockSize - len (r ):], r )
153
- copy (params [1 * blockSize + blockSize - len (s ):], s )
154
- hashToBytes (c , params [2 * blockSize :3 * blockSize ], hash )
155
- copy (params [3 * blockSize :5 * blockSize ], pub .q [1 :]) // strip 0x04 prefix
181
+ p := params [:0 ]
182
+ p = appendBlock (p , blockSize , r )
183
+ p = appendBlock (p , blockSize , s )
184
+ p = appendBlock (p , blockSize , hashToBytes (c , hash ))
185
+ p = appendBlock (p , blockSize , pub .q [1 :1 + len (pub .q )/ 2 ])
186
+ p = appendBlock (p , blockSize , pub .q [1 + len (pub .q )/ 2 :])
156
187
if kdsa (functionCode , & params ) != 0 {
157
188
return errors .New ("invalid signature" )
158
189
}
0 commit comments