Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/ecdsa/keys.py: 55%

378 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-25 07:19 +0000

1""" 

2Primary classes for performing signing and verification operations. 

3""" 

4 

5import binascii 

6from hashlib import sha1 

7import os 

8from six import PY2, b 

9from . import ecdsa, eddsa 

10from . import der 

11from . import rfc6979 

12from . import ellipticcurve 

13from .curves import NIST192p, Curve, Ed25519, Ed448 

14from .ecdsa import RSZeroError 

15from .util import string_to_number, number_to_string, randrange 

16from .util import sigencode_string, sigdecode_string, bit_length 

17from .util import ( 

18 oid_ecPublicKey, 

19 encoded_oid_ecPublicKey, 

20 oid_ecDH, 

21 oid_ecMQV, 

22 MalformedSignature, 

23) 

24from ._compat import normalise_bytes 

25from .errors import MalformedPointError 

26from .ellipticcurve import PointJacobi, CurveEdTw 

27 

28 

29__all__ = [ 

30 "BadSignatureError", 

31 "BadDigestError", 

32 "VerifyingKey", 

33 "SigningKey", 

34 "MalformedPointError", 

35] 

36 

37 

38class BadSignatureError(Exception): 

39 """ 

40 Raised when verification of signature failed. 

41 

42 Will be raised irrespective of reason of the failure: 

43 

44 * the calculated or provided hash does not match the signature 

45 * the signature does not match the curve/public key 

46 * the encoding of the signature is malformed 

47 * the size of the signature does not match the curve of the VerifyingKey 

48 """ 

49 

50 pass 

51 

52 

53class BadDigestError(Exception): 

54 """Raised in case the selected hash is too large for the curve.""" 

55 

56 pass 

57 

58 

59def _truncate_and_convert_digest(digest, curve, allow_truncate): 

60 """Truncates and converts digest to an integer.""" 

61 if not allow_truncate: 

62 if len(digest) > curve.baselen: 

63 raise BadDigestError( 

64 "this curve ({0}) is too short " 

65 "for the length of your digest ({1})".format( 

66 curve.name, 8 * len(digest) 

67 ) 

68 ) 

69 else: 

70 digest = digest[: curve.baselen] 

71 number = string_to_number(digest) 

72 if allow_truncate: 

73 max_length = bit_length(curve.order) 

74 # we don't use bit_length(number) as that truncates leading zeros 

75 length = len(digest) * 8 

76 

77 # See NIST FIPS 186-4: 

78 # 

79 # When the length of the output of the hash function is greater 

80 # than N (i.e., the bit length of q), then the leftmost N bits of 

81 # the hash function output block shall be used in any calculation 

82 # using the hash function output during the generation or 

83 # verification of a digital signature. 

84 # 

85 # as such, we need to shift-out the low-order bits: 

86 number >>= max(0, length - max_length) 

87 

88 return number 

89 

90 

91class VerifyingKey(object): 

92 """ 

93 Class for handling keys that can verify signatures (public keys). 

94 

95 :ivar `~ecdsa.curves.Curve` ~.curve: The Curve over which all the 

96 cryptographic operations will take place 

97 :ivar default_hashfunc: the function that will be used for hashing the 

98 data. Should implement the same API as hashlib.sha1 

99 :vartype default_hashfunc: callable 

100 :ivar pubkey: the actual public key 

101 :vartype pubkey: ~ecdsa.ecdsa.Public_key 

102 """ 

103 

104 def __init__(self, _error__please_use_generate=None): 

105 """Unsupported, please use one of the classmethods to initialise.""" 

106 if not _error__please_use_generate: 

107 raise TypeError( 

108 "Please use VerifyingKey.generate() to construct me" 

109 ) 

110 self.curve = None 

111 self.default_hashfunc = None 

112 self.pubkey = None 

113 

114 def __repr__(self): 

115 pub_key = self.to_string("compressed") 

116 if self.default_hashfunc: 

117 hash_name = self.default_hashfunc().name 

118 else: 

119 hash_name = "None" 

120 return "VerifyingKey.from_string({0!r}, {1!r}, {2})".format( 

121 pub_key, self.curve, hash_name 

122 ) 

123 

124 def __eq__(self, other): 

125 """Return True if the points are identical, False otherwise.""" 

126 if isinstance(other, VerifyingKey): 

127 return self.curve == other.curve and self.pubkey == other.pubkey 

128 return NotImplemented 

129 

130 def __ne__(self, other): 

131 """Return False if the points are identical, True otherwise.""" 

132 return not self == other 

133 

134 @classmethod 

135 def from_public_point( 

136 cls, point, curve=NIST192p, hashfunc=sha1, validate_point=True 

137 ): 

138 """ 

139 Initialise the object from a Point object. 

140 

141 This is a low-level method, generally you will not want to use it. 

142 

143 :param point: The point to wrap around, the actual public key 

144 :type point: ~ecdsa.ellipticcurve.AbstractPoint 

145 :param curve: The curve on which the point needs to reside, defaults 

146 to NIST192p 

147 :type curve: ~ecdsa.curves.Curve 

148 :param hashfunc: The default hash function that will be used for 

149 verification, needs to implement the same interface 

150 as :py:class:`hashlib.sha1` 

151 :type hashfunc: callable 

152 :type bool validate_point: whether to check if the point lays on curve 

153 should always be used if the public point is not a result 

154 of our own calculation 

155 

156 :raises MalformedPointError: if the public point does not lay on the 

157 curve 

158 

159 :return: Initialised VerifyingKey object 

160 :rtype: VerifyingKey 

161 """ 

162 self = cls(_error__please_use_generate=True) 

163 if isinstance(curve.curve, CurveEdTw): 

164 raise ValueError("Method incompatible with Edwards curves") 

165 if not isinstance(point, ellipticcurve.PointJacobi): 

166 point = ellipticcurve.PointJacobi.from_affine(point) 

167 self.curve = curve 

168 self.default_hashfunc = hashfunc 

169 try: 

170 self.pubkey = ecdsa.Public_key( 

171 curve.generator, point, validate_point 

172 ) 

173 except ecdsa.InvalidPointError: 

174 raise MalformedPointError("Point does not lay on the curve") 

175 self.pubkey.order = curve.order 

176 return self 

177 

178 def precompute(self, lazy=False): 

179 """ 

180 Precompute multiplication tables for faster signature verification. 

181 

182 Calling this method will cause the library to precompute the 

183 scalar multiplication tables, used in signature verification. 

184 While it's an expensive operation (comparable to performing 

185 as many signatures as the bit size of the curve, i.e. 256 for NIST256p) 

186 it speeds up verification 2 times. You should call this method 

187 if you expect to verify hundreds of signatures (or more) using the same 

188 VerifyingKey object. 

189 

190 Note: You should call this method only once, this method generates a 

191 new precomputation table every time it's called. 

192 

193 :param bool lazy: whether to calculate the precomputation table now 

194 (if set to False) or if it should be delayed to the time of first 

195 use (when set to True) 

196 """ 

197 if isinstance(self.curve.curve, CurveEdTw): 

198 pt = self.pubkey.point 

199 self.pubkey.point = ellipticcurve.PointEdwards( 

200 pt.curve(), 

201 pt.x(), 

202 pt.y(), 

203 1, 

204 pt.x() * pt.y(), 

205 self.curve.order, 

206 generator=True, 

207 ) 

208 else: 

209 self.pubkey.point = ellipticcurve.PointJacobi.from_affine( 

210 self.pubkey.point, True 

211 ) 

212 # as precomputation in now delayed to the time of first use of the 

213 # point and we were asked specifically to precompute now, make 

214 # sure the precomputation is performed now to preserve the behaviour 

215 if not lazy: 

216 self.pubkey.point * 2 

217 

218 @classmethod 

219 def from_string( 

220 cls, 

221 string, 

222 curve=NIST192p, 

223 hashfunc=sha1, 

224 validate_point=True, 

225 valid_encodings=None, 

226 ): 

227 """ 

228 Initialise the object from byte encoding of public key. 

229 

230 The method does accept and automatically detect the type of point 

231 encoding used. It supports the :term:`raw encoding`, 

232 :term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings. 

233 It also works with the native encoding of Ed25519 and Ed448 public 

234 keys (technically those are compressed, but encoded differently than 

235 in other signature systems). 

236 

237 Note, while the method is named "from_string" it's a misnomer from 

238 Python 2 days when there were no binary strings. In Python 3 the 

239 input needs to be a bytes-like object. 

240 

241 :param string: single point encoding of the public key 

242 :type string: :term:`bytes-like object` 

243 :param curve: the curve on which the public key is expected to lay 

244 :type curve: ~ecdsa.curves.Curve 

245 :param hashfunc: The default hash function that will be used for 

246 verification, needs to implement the same interface as 

247 hashlib.sha1. Ignored for EdDSA. 

248 :type hashfunc: callable 

249 :param validate_point: whether to verify that the point lays on the 

250 provided curve or not, defaults to True. Ignored for EdDSA. 

251 :type validate_point: bool 

252 :param valid_encodings: list of acceptable point encoding formats, 

253 supported ones are: :term:`uncompressed`, :term:`compressed`, 

254 :term:`hybrid`, and :term:`raw encoding` (specified with ``raw`` 

255 name). All formats by default (specified with ``None``). 

256 Ignored for EdDSA. 

257 :type valid_encodings: :term:`set-like object` 

258 

259 :raises MalformedPointError: if the public point does not lay on the 

260 curve or the encoding is invalid 

261 

262 :return: Initialised VerifyingKey object 

263 :rtype: VerifyingKey 

264 """ 

265 if isinstance(curve.curve, CurveEdTw): 

266 self = cls(_error__please_use_generate=True) 

267 self.curve = curve 

268 self.default_hashfunc = None # ignored for EdDSA 

269 try: 

270 self.pubkey = eddsa.PublicKey(curve.generator, string) 

271 except ValueError: 

272 raise MalformedPointError("Malformed point for the curve") 

273 return self 

274 

275 point = PointJacobi.from_bytes( 

276 curve.curve, 

277 string, 

278 validate_encoding=validate_point, 

279 valid_encodings=valid_encodings, 

280 ) 

281 return cls.from_public_point(point, curve, hashfunc, validate_point) 

282 

283 @classmethod 

284 def from_pem( 

285 cls, 

286 string, 

287 hashfunc=sha1, 

288 valid_encodings=None, 

289 valid_curve_encodings=None, 

290 ): 

291 """ 

292 Initialise from public key stored in :term:`PEM` format. 

293 

294 The PEM header of the key should be ``BEGIN PUBLIC KEY``. 

295 

296 See the :func:`~VerifyingKey.from_der()` method for details of the 

297 format supported. 

298 

299 Note: only a single PEM object decoding is supported in provided 

300 string. 

301 

302 :param string: text with PEM-encoded public ECDSA key 

303 :type string: str 

304 :param valid_encodings: list of allowed point encodings. 

305 By default :term:`uncompressed`, :term:`compressed`, and 

306 :term:`hybrid`. To read malformed files, include 

307 :term:`raw encoding` with ``raw`` in the list. 

308 :type valid_encodings: :term:`set-like object` 

309 :param valid_curve_encodings: list of allowed encoding formats 

310 for curve parameters. By default (``None``) all are supported: 

311 ``named_curve`` and ``explicit``. 

312 :type valid_curve_encodings: :term:`set-like object` 

313 

314 

315 :return: Initialised VerifyingKey object 

316 :rtype: VerifyingKey 

317 """ 

318 return cls.from_der( 

319 der.unpem(string), 

320 hashfunc=hashfunc, 

321 valid_encodings=valid_encodings, 

322 valid_curve_encodings=valid_curve_encodings, 

323 ) 

324 

325 @classmethod 

326 def from_der( 

327 cls, 

328 string, 

329 hashfunc=sha1, 

330 valid_encodings=None, 

331 valid_curve_encodings=None, 

332 ): 

333 """ 

334 Initialise the key stored in :term:`DER` format. 

335 

336 The expected format of the key is the SubjectPublicKeyInfo structure 

337 from RFC5912 (for RSA keys, it's known as the PKCS#1 format):: 

338 

339 SubjectPublicKeyInfo {PUBLIC-KEY: IOSet} ::= SEQUENCE { 

340 algorithm AlgorithmIdentifier {PUBLIC-KEY, {IOSet}}, 

341 subjectPublicKey BIT STRING 

342 } 

343 

344 Note: only public EC keys are supported by this method. The 

345 SubjectPublicKeyInfo.algorithm.algorithm field must specify 

346 id-ecPublicKey (see RFC3279). 

347 

348 Only the named curve encoding is supported, thus the 

349 SubjectPublicKeyInfo.algorithm.parameters field needs to be an 

350 object identifier. A sequence in that field indicates an explicit 

351 parameter curve encoding, this format is not supported. A NULL object 

352 in that field indicates an "implicitlyCA" encoding, where the curve 

353 parameters come from CA certificate, those, again, are not supported. 

354 

355 :param string: binary string with the DER encoding of public ECDSA key 

356 :type string: bytes-like object 

357 :param valid_encodings: list of allowed point encodings. 

358 By default :term:`uncompressed`, :term:`compressed`, and 

359 :term:`hybrid`. To read malformed files, include 

360 :term:`raw encoding` with ``raw`` in the list. 

361 :type valid_encodings: :term:`set-like object` 

362 :param valid_curve_encodings: list of allowed encoding formats 

363 for curve parameters. By default (``None``) all are supported: 

364 ``named_curve`` and ``explicit``. 

365 :type valid_curve_encodings: :term:`set-like object` 

366 

367 :return: Initialised VerifyingKey object 

368 :rtype: VerifyingKey 

369 """ 

370 if valid_encodings is None: 

371 valid_encodings = set(["uncompressed", "compressed", "hybrid"]) 

372 string = normalise_bytes(string) 

373 # [[oid_ecPublicKey,oid_curve], point_str_bitstring] 

374 s1, empty = der.remove_sequence(string) 

375 if empty != b"": 

376 raise der.UnexpectedDER( 

377 "trailing junk after DER pubkey: %s" % binascii.hexlify(empty) 

378 ) 

379 s2, point_str_bitstring = der.remove_sequence(s1) 

380 # s2 = oid_ecPublicKey,oid_curve 

381 oid_pk, rest = der.remove_object(s2) 

382 if oid_pk in (Ed25519.oid, Ed448.oid): 

383 if oid_pk == Ed25519.oid: 

384 curve = Ed25519 

385 else: 

386 assert oid_pk == Ed448.oid 

387 curve = Ed448 

388 point_str, empty = der.remove_bitstring(point_str_bitstring, 0) 

389 if empty: 

390 raise der.UnexpectedDER("trailing junk after public key") 

391 return cls.from_string(point_str, curve, None) 

392 if not oid_pk == oid_ecPublicKey: 

393 raise der.UnexpectedDER( 

394 "Unexpected object identifier in DER " 

395 "encoding: {0!r}".format(oid_pk) 

396 ) 

397 curve = Curve.from_der(rest, valid_curve_encodings) 

398 point_str, empty = der.remove_bitstring(point_str_bitstring, 0) 

399 if empty != b"": 

400 raise der.UnexpectedDER( 

401 "trailing junk after pubkey pointstring: %s" 

402 % binascii.hexlify(empty) 

403 ) 

404 # raw encoding of point is invalid in DER files 

405 if len(point_str) == curve.verifying_key_length: 

406 raise der.UnexpectedDER("Malformed encoding of public point") 

407 return cls.from_string( 

408 point_str, 

409 curve, 

410 hashfunc=hashfunc, 

411 valid_encodings=valid_encodings, 

412 ) 

413 

414 @classmethod 

415 def from_public_key_recovery( 

416 cls, 

417 signature, 

418 data, 

419 curve, 

420 hashfunc=sha1, 

421 sigdecode=sigdecode_string, 

422 allow_truncate=True, 

423 ): 

424 """ 

425 Return keys that can be used as verifiers of the provided signature. 

426 

427 Tries to recover the public key that can be used to verify the 

428 signature, usually returns two keys like that. 

429 

430 :param signature: the byte string with the encoded signature 

431 :type signature: bytes-like object 

432 :param data: the data to be hashed for signature verification 

433 :type data: bytes-like object 

434 :param curve: the curve over which the signature was performed 

435 :type curve: ~ecdsa.curves.Curve 

436 :param hashfunc: The default hash function that will be used for 

437 verification, needs to implement the same interface as hashlib.sha1 

438 :type hashfunc: callable 

439 :param sigdecode: Callable to define the way the signature needs to 

440 be decoded to an object, needs to handle `signature` as the 

441 first parameter, the curve order (an int) as the second and return 

442 a tuple with two integers, "r" as the first one and "s" as the 

443 second one. See :func:`ecdsa.util.sigdecode_string` and 

444 :func:`ecdsa.util.sigdecode_der` for examples. 

445 :param bool allow_truncate: if True, the provided hashfunc can generate 

446 values larger than the bit size of the order of the curve, the 

447 extra bits (at the end of the digest) will be truncated. 

448 :type sigdecode: callable 

449 

450 :return: Initialised VerifyingKey objects 

451 :rtype: list of VerifyingKey 

452 """ 

453 if isinstance(curve.curve, CurveEdTw): 

454 raise ValueError("Method unsupported for Edwards curves") 

455 data = normalise_bytes(data) 

456 digest = hashfunc(data).digest() 

457 return cls.from_public_key_recovery_with_digest( 

458 signature, 

459 digest, 

460 curve, 

461 hashfunc=hashfunc, 

462 sigdecode=sigdecode, 

463 allow_truncate=allow_truncate, 

464 ) 

465 

466 @classmethod 

467 def from_public_key_recovery_with_digest( 

468 cls, 

469 signature, 

470 digest, 

471 curve, 

472 hashfunc=sha1, 

473 sigdecode=sigdecode_string, 

474 allow_truncate=False, 

475 ): 

476 """ 

477 Return keys that can be used as verifiers of the provided signature. 

478 

479 Tries to recover the public key that can be used to verify the 

480 signature, usually returns two keys like that. 

481 

482 :param signature: the byte string with the encoded signature 

483 :type signature: bytes-like object 

484 :param digest: the hash value of the message signed by the signature 

485 :type digest: bytes-like object 

486 :param curve: the curve over which the signature was performed 

487 :type curve: ~ecdsa.curves.Curve 

488 :param hashfunc: The default hash function that will be used for 

489 verification, needs to implement the same interface as hashlib.sha1 

490 :type hashfunc: callable 

491 :param sigdecode: Callable to define the way the signature needs to 

492 be decoded to an object, needs to handle `signature` as the 

493 first parameter, the curve order (an int) as the second and return 

494 a tuple with two integers, "r" as the first one and "s" as the 

495 second one. See :func:`ecdsa.util.sigdecode_string` and 

496 :func:`ecdsa.util.sigdecode_der` for examples. 

497 :type sigdecode: callable 

498 :param bool allow_truncate: if True, the provided hashfunc can generate 

499 values larger than the bit size of the order of the curve (and 

500 the length of provided `digest`), the extra bits (at the end of the 

501 digest) will be truncated. 

502 

503 :return: Initialised VerifyingKey object 

504 :rtype: VerifyingKey 

505 """ 

506 if isinstance(curve.curve, CurveEdTw): 

507 raise ValueError("Method unsupported for Edwards curves") 

508 generator = curve.generator 

509 r, s = sigdecode(signature, generator.order()) 

510 sig = ecdsa.Signature(r, s) 

511 

512 digest = normalise_bytes(digest) 

513 digest_as_number = _truncate_and_convert_digest( 

514 digest, curve, allow_truncate 

515 ) 

516 pks = sig.recover_public_keys(digest_as_number, generator) 

517 

518 # Transforms the ecdsa.Public_key object into a VerifyingKey 

519 verifying_keys = [ 

520 cls.from_public_point(pk.point, curve, hashfunc) for pk in pks 

521 ] 

522 return verifying_keys 

523 

524 def to_string(self, encoding="raw"): 

525 """ 

526 Convert the public key to a byte string. 

527 

528 The method by default uses the :term:`raw encoding` (specified 

529 by `encoding="raw"`. It can also output keys in :term:`uncompressed`, 

530 :term:`compressed` and :term:`hybrid` formats. 

531 

532 Remember that the curve identification is not part of the encoding 

533 so to decode the point using :func:`~VerifyingKey.from_string`, curve 

534 needs to be specified. 

535 

536 Note: while the method is called "to_string", it's a misnomer from 

537 Python 2 days when character strings and byte strings shared type. 

538 On Python 3 the returned type will be `bytes`. 

539 

540 :return: :term:`raw encoding` of the public key (public point) on the 

541 curve 

542 :rtype: bytes 

543 """ 

544 assert encoding in ("raw", "uncompressed", "compressed", "hybrid") 

545 return self.pubkey.point.to_bytes(encoding) 

546 

547 def to_pem( 

548 self, point_encoding="uncompressed", curve_parameters_encoding=None 

549 ): 

550 """ 

551 Convert the public key to the :term:`PEM` format. 

552 

553 The PEM header of the key will be ``BEGIN PUBLIC KEY``. 

554 

555 The format of the key is described in the 

556 :func:`~VerifyingKey.from_der()` method. 

557 This method supports only "named curve" encoding of keys. 

558 

559 :param str point_encoding: specification of the encoding format 

560 of public keys. "uncompressed" is most portable, "compressed" is 

561 smallest. "hybrid" is uncommon and unsupported by most 

562 implementations, it is as big as "uncompressed". 

563 :param str curve_parameters_encoding: the encoding for curve parameters 

564 to use, by default tries to use ``named_curve`` encoding, 

565 if that is not possible, falls back to ``explicit`` encoding. 

566 

567 :return: portable encoding of the public key 

568 :rtype: bytes 

569 

570 .. warning:: The PEM is encoded to US-ASCII, it needs to be 

571 re-encoded if the system is incompatible (e.g. uses UTF-16) 

572 """ 

573 return der.topem( 

574 self.to_der(point_encoding, curve_parameters_encoding), 

575 "PUBLIC KEY", 

576 ) 

577 

578 def to_der( 

579 self, point_encoding="uncompressed", curve_parameters_encoding=None 

580 ): 

581 """ 

582 Convert the public key to the :term:`DER` format. 

583 

584 The format of the key is described in the 

585 :func:`~VerifyingKey.from_der()` method. 

586 This method supports only "named curve" encoding of keys. 

587 

588 :param str point_encoding: specification of the encoding format 

589 of public keys. "uncompressed" is most portable, "compressed" is 

590 smallest. "hybrid" is uncommon and unsupported by most 

591 implementations, it is as big as "uncompressed". 

592 :param str curve_parameters_encoding: the encoding for curve parameters 

593 to use, by default tries to use ``named_curve`` encoding, 

594 if that is not possible, falls back to ``explicit`` encoding. 

595 

596 :return: DER encoding of the public key 

597 :rtype: bytes 

598 """ 

599 if point_encoding == "raw": 

600 raise ValueError("raw point_encoding not allowed in DER") 

601 point_str = self.to_string(point_encoding) 

602 if isinstance(self.curve.curve, CurveEdTw): 

603 return der.encode_sequence( 

604 der.encode_sequence(der.encode_oid(*self.curve.oid)), 

605 der.encode_bitstring(bytes(point_str), 0), 

606 ) 

607 return der.encode_sequence( 

608 der.encode_sequence( 

609 encoded_oid_ecPublicKey, 

610 self.curve.to_der(curve_parameters_encoding, point_encoding), 

611 ), 

612 # 0 is the number of unused bits in the 

613 # bit string 

614 der.encode_bitstring(point_str, 0), 

615 ) 

616 

617 def verify( 

618 self, 

619 signature, 

620 data, 

621 hashfunc=None, 

622 sigdecode=sigdecode_string, 

623 allow_truncate=True, 

624 ): 

625 """ 

626 Verify a signature made over provided data. 

627 

628 Will hash `data` to verify the signature. 

629 

630 By default expects signature in :term:`raw encoding`. Can also be used 

631 to verify signatures in ASN.1 DER encoding by using 

632 :func:`ecdsa.util.sigdecode_der` 

633 as the `sigdecode` parameter. 

634 

635 :param signature: encoding of the signature 

636 :type signature: sigdecode method dependent 

637 :param data: data signed by the `signature`, will be hashed using 

638 `hashfunc`, if specified, or default hash function 

639 :type data: :term:`bytes-like object` 

640 :param hashfunc: The default hash function that will be used for 

641 verification, needs to implement the same interface as hashlib.sha1 

642 :type hashfunc: callable 

643 :param sigdecode: Callable to define the way the signature needs to 

644 be decoded to an object, needs to handle `signature` as the 

645 first parameter, the curve order (an int) as the second and return 

646 a tuple with two integers, "r" as the first one and "s" as the 

647 second one. See :func:`ecdsa.util.sigdecode_string` and 

648 :func:`ecdsa.util.sigdecode_der` for examples. 

649 :type sigdecode: callable 

650 :param bool allow_truncate: if True, the provided digest can have 

651 bigger bit-size than the order of the curve, the extra bits (at 

652 the end of the digest) will be truncated. Use it when verifying 

653 SHA-384 output using NIST256p or in similar situations. Defaults to 

654 True. 

655 

656 :raises BadSignatureError: if the signature is invalid or malformed 

657 

658 :return: True if the verification was successful 

659 :rtype: bool 

660 """ 

661 # signature doesn't have to be a bytes-like-object so don't normalise 

662 # it, the decoders will do that 

663 data = normalise_bytes(data) 

664 if isinstance(self.curve.curve, CurveEdTw): 

665 signature = normalise_bytes(signature) 

666 try: 

667 return self.pubkey.verify(data, signature) 

668 except (ValueError, MalformedPointError) as e: 

669 raise BadSignatureError("Signature verification failed", e) 

670 

671 hashfunc = hashfunc or self.default_hashfunc 

672 digest = hashfunc(data).digest() 

673 return self.verify_digest(signature, digest, sigdecode, allow_truncate) 

674 

675 def verify_digest( 

676 self, 

677 signature, 

678 digest, 

679 sigdecode=sigdecode_string, 

680 allow_truncate=False, 

681 ): 

682 """ 

683 Verify a signature made over provided hash value. 

684 

685 By default expects signature in :term:`raw encoding`. Can also be used 

686 to verify signatures in ASN.1 DER encoding by using 

687 :func:`ecdsa.util.sigdecode_der` 

688 as the `sigdecode` parameter. 

689 

690 :param signature: encoding of the signature 

691 :type signature: sigdecode method dependent 

692 :param digest: raw hash value that the signature authenticates. 

693 :type digest: :term:`bytes-like object` 

694 :param sigdecode: Callable to define the way the signature needs to 

695 be decoded to an object, needs to handle `signature` as the 

696 first parameter, the curve order (an int) as the second and return 

697 a tuple with two integers, "r" as the first one and "s" as the 

698 second one. See :func:`ecdsa.util.sigdecode_string` and 

699 :func:`ecdsa.util.sigdecode_der` for examples. 

700 :type sigdecode: callable 

701 :param bool allow_truncate: if True, the provided digest can have 

702 bigger bit-size than the order of the curve, the extra bits (at 

703 the end of the digest) will be truncated. Use it when verifying 

704 SHA-384 output using NIST256p or in similar situations. 

705 

706 :raises BadSignatureError: if the signature is invalid or malformed 

707 :raises BadDigestError: if the provided digest is too big for the curve 

708 associated with this VerifyingKey and allow_truncate was not set 

709 

710 :return: True if the verification was successful 

711 :rtype: bool 

712 """ 

713 # signature doesn't have to be a bytes-like-object so don't normalise 

714 # it, the decoders will do that 

715 digest = normalise_bytes(digest) 

716 number = _truncate_and_convert_digest( 

717 digest, 

718 self.curve, 

719 allow_truncate, 

720 ) 

721 

722 try: 

723 r, s = sigdecode(signature, self.pubkey.order) 

724 except (der.UnexpectedDER, MalformedSignature) as e: 

725 raise BadSignatureError("Malformed formatting of signature", e) 

726 sig = ecdsa.Signature(r, s) 

727 if self.pubkey.verifies(number, sig): 

728 return True 

729 raise BadSignatureError("Signature verification failed") 

730 

731 

732class SigningKey(object): 

733 """ 

734 Class for handling keys that can create signatures (private keys). 

735 

736 :ivar `~ecdsa.curves.Curve` curve: The Curve over which all the 

737 cryptographic operations will take place 

738 :ivar default_hashfunc: the function that will be used for hashing the 

739 data. Should implement the same API as :py:class:`hashlib.sha1` 

740 :ivar int baselen: the length of a :term:`raw encoding` of private key 

741 :ivar `~ecdsa.keys.VerifyingKey` verifying_key: the public key 

742 associated with this private key 

743 :ivar `~ecdsa.ecdsa.Private_key` privkey: the actual private key 

744 """ 

745 

746 def __init__(self, _error__please_use_generate=None): 

747 """Unsupported, please use one of the classmethods to initialise.""" 

748 if not _error__please_use_generate: 

749 raise TypeError("Please use SigningKey.generate() to construct me") 

750 self.curve = None 

751 self.default_hashfunc = None 

752 self.baselen = None 

753 self.verifying_key = None 

754 self.privkey = None 

755 

756 def __eq__(self, other): 

757 """Return True if the points are identical, False otherwise.""" 

758 if isinstance(other, SigningKey): 

759 return ( 

760 self.curve == other.curve 

761 and self.verifying_key == other.verifying_key 

762 and self.privkey == other.privkey 

763 ) 

764 return NotImplemented 

765 

766 def __ne__(self, other): 

767 """Return False if the points are identical, True otherwise.""" 

768 return not self == other 

769 

770 @classmethod 

771 def _twisted_edwards_keygen(cls, curve, entropy): 

772 """Generate a private key on a Twisted Edwards curve.""" 

773 if not entropy: 

774 entropy = os.urandom 

775 random = entropy(curve.baselen) 

776 private_key = eddsa.PrivateKey(curve.generator, random) 

777 public_key = private_key.public_key() 

778 

779 verifying_key = VerifyingKey.from_string( 

780 public_key.public_key(), curve 

781 ) 

782 

783 self = cls(_error__please_use_generate=True) 

784 self.curve = curve 

785 self.default_hashfunc = None 

786 self.baselen = curve.baselen 

787 self.privkey = private_key 

788 self.verifying_key = verifying_key 

789 return self 

790 

791 @classmethod 

792 def _weierstrass_keygen(cls, curve, entropy, hashfunc): 

793 """Generate a private key on a Weierstrass curve.""" 

794 secexp = randrange(curve.order, entropy) 

795 return cls.from_secret_exponent(secexp, curve, hashfunc) 

796 

797 @classmethod 

798 def generate(cls, curve=NIST192p, entropy=None, hashfunc=sha1): 

799 """ 

800 Generate a random private key. 

801 

802 :param curve: The curve on which the point needs to reside, defaults 

803 to NIST192p 

804 :type curve: ~ecdsa.curves.Curve 

805 :param entropy: Source of randomness for generating the private keys, 

806 should provide cryptographically secure random numbers if the keys 

807 need to be secure. Uses os.urandom() by default. 

808 :type entropy: callable 

809 :param hashfunc: The default hash function that will be used for 

810 signing, needs to implement the same interface 

811 as hashlib.sha1 

812 :type hashfunc: callable 

813 

814 :return: Initialised SigningKey object 

815 :rtype: SigningKey 

816 """ 

817 if isinstance(curve.curve, CurveEdTw): 

818 return cls._twisted_edwards_keygen(curve, entropy) 

819 return cls._weierstrass_keygen(curve, entropy, hashfunc) 

820 

821 @classmethod 

822 def from_secret_exponent(cls, secexp, curve=NIST192p, hashfunc=sha1): 

823 """ 

824 Create a private key from a random integer. 

825 

826 Note: it's a low level method, it's recommended to use the 

827 :func:`~SigningKey.generate` method to create private keys. 

828 

829 :param int secexp: secret multiplier (the actual private key in ECDSA). 

830 Needs to be an integer between 1 and the curve order. 

831 :param curve: The curve on which the point needs to reside 

832 :type curve: ~ecdsa.curves.Curve 

833 :param hashfunc: The default hash function that will be used for 

834 signing, needs to implement the same interface 

835 as hashlib.sha1 

836 :type hashfunc: callable 

837 

838 :raises MalformedPointError: when the provided secexp is too large 

839 or too small for the curve selected 

840 :raises RuntimeError: if the generation of public key from private 

841 key failed 

842 

843 :return: Initialised SigningKey object 

844 :rtype: SigningKey 

845 """ 

846 if isinstance(curve.curve, CurveEdTw): 

847 raise ValueError( 

848 "Edwards keys don't support setting the secret scalar " 

849 "(exponent) directly" 

850 ) 

851 self = cls(_error__please_use_generate=True) 

852 self.curve = curve 

853 self.default_hashfunc = hashfunc 

854 self.baselen = curve.baselen 

855 n = curve.order 

856 if not 1 <= secexp < n: 

857 raise MalformedPointError( 

858 "Invalid value for secexp, expected integer " 

859 "between 1 and {0}".format(n) 

860 ) 

861 pubkey_point = curve.generator * secexp 

862 if hasattr(pubkey_point, "scale"): 

863 pubkey_point = pubkey_point.scale() 

864 self.verifying_key = VerifyingKey.from_public_point( 

865 pubkey_point, curve, hashfunc, False 

866 ) 

867 pubkey = self.verifying_key.pubkey 

868 self.privkey = ecdsa.Private_key(pubkey, secexp) 

869 self.privkey.order = n 

870 return self 

871 

872 @classmethod 

873 def from_string(cls, string, curve=NIST192p, hashfunc=sha1): 

874 """ 

875 Decode the private key from :term:`raw encoding`. 

876 

877 Note: the name of this method is a misnomer coming from days of 

878 Python 2, when binary strings and character strings shared a type. 

879 In Python 3, the expected type is `bytes`. 

880 

881 :param string: the raw encoding of the private key 

882 :type string: :term:`bytes-like object` 

883 :param curve: The curve on which the point needs to reside 

884 :type curve: ~ecdsa.curves.Curve 

885 :param hashfunc: The default hash function that will be used for 

886 signing, needs to implement the same interface 

887 as hashlib.sha1 

888 :type hashfunc: callable 

889 

890 :raises MalformedPointError: if the length of encoding doesn't match 

891 the provided curve or the encoded values is too large 

892 :raises RuntimeError: if the generation of public key from private 

893 key failed 

894 

895 :return: Initialised SigningKey object 

896 :rtype: SigningKey 

897 """ 

898 string = normalise_bytes(string) 

899 

900 if len(string) != curve.baselen: 

901 raise MalformedPointError( 

902 "Invalid length of private key, received {0}, " 

903 "expected {1}".format(len(string), curve.baselen) 

904 ) 

905 if isinstance(curve.curve, CurveEdTw): 

906 self = cls(_error__please_use_generate=True) 

907 self.curve = curve 

908 self.default_hashfunc = None # Ignored for EdDSA 

909 self.baselen = curve.baselen 

910 self.privkey = eddsa.PrivateKey(curve.generator, string) 

911 self.verifying_key = VerifyingKey.from_string( 

912 self.privkey.public_key().public_key(), curve 

913 ) 

914 return self 

915 secexp = string_to_number(string) 

916 return cls.from_secret_exponent(secexp, curve, hashfunc) 

917 

918 @classmethod 

919 def from_pem(cls, string, hashfunc=sha1, valid_curve_encodings=None): 

920 """ 

921 Initialise from key stored in :term:`PEM` format. 

922 

923 The PEM formats supported are the un-encrypted RFC5915 

924 (the ssleay format) supported by OpenSSL, and the more common 

925 un-encrypted RFC5958 (the PKCS #8 format). 

926 

927 The legacy format files have the header with the string 

928 ``BEGIN EC PRIVATE KEY``. 

929 PKCS#8 files have the header ``BEGIN PRIVATE KEY``. 

930 Encrypted files (ones that include the string 

931 ``Proc-Type: 4,ENCRYPTED`` 

932 right after the PEM header) are not supported. 

933 

934 See :func:`~SigningKey.from_der` for ASN.1 syntax of the objects in 

935 this files. 

936 

937 :param string: text with PEM-encoded private ECDSA key 

938 :type string: str 

939 :param valid_curve_encodings: list of allowed encoding formats 

940 for curve parameters. By default (``None``) all are supported: 

941 ``named_curve`` and ``explicit``. 

942 :type valid_curve_encodings: :term:`set-like object` 

943 

944 

945 :raises MalformedPointError: if the length of encoding doesn't match 

946 the provided curve or the encoded values is too large 

947 :raises RuntimeError: if the generation of public key from private 

948 key failed 

949 :raises UnexpectedDER: if the encoding of the PEM file is incorrect 

950 

951 :return: Initialised SigningKey object 

952 :rtype: SigningKey 

953 """ 

954 if not PY2 and isinstance(string, str): # pragma: no branch 

955 string = string.encode() 

956 

957 # The privkey pem may have multiple sections, commonly it also has 

958 # "EC PARAMETERS", we need just "EC PRIVATE KEY". PKCS#8 should not 

959 # have the "EC PARAMETERS" section; it's just "PRIVATE KEY". 

960 private_key_index = string.find(b"-----BEGIN EC PRIVATE KEY-----") 

961 if private_key_index == -1: 

962 private_key_index = string.index(b"-----BEGIN PRIVATE KEY-----") 

963 

964 return cls.from_der( 

965 der.unpem(string[private_key_index:]), 

966 hashfunc, 

967 valid_curve_encodings, 

968 ) 

969 

970 @classmethod 

971 def from_der(cls, string, hashfunc=sha1, valid_curve_encodings=None): 

972 """ 

973 Initialise from key stored in :term:`DER` format. 

974 

975 The DER formats supported are the un-encrypted RFC5915 

976 (the ssleay format) supported by OpenSSL, and the more common 

977 un-encrypted RFC5958 (the PKCS #8 format). 

978 

979 Both formats contain an ASN.1 object following the syntax specified 

980 in RFC5915:: 

981 

982 ECPrivateKey ::= SEQUENCE { 

983 version INTEGER { ecPrivkeyVer1(1) }} (ecPrivkeyVer1), 

984 privateKey OCTET STRING, 

985 parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 

986 publicKey [1] BIT STRING OPTIONAL 

987 } 

988 

989 `publicKey` field is ignored completely (errors, if any, in it will 

990 be undetected). 

991 

992 Two formats are supported for the `parameters` field: the named 

993 curve and the explicit encoding of curve parameters. 

994 In the legacy ssleay format, this implementation requires the optional 

995 `parameters` field to get the curve name. In PKCS #8 format, the curve 

996 is part of the PrivateKeyAlgorithmIdentifier. 

997 

998 The PKCS #8 format includes an ECPrivateKey object as the `privateKey` 

999 field within a larger structure:: 

1000 

1001 OneAsymmetricKey ::= SEQUENCE { 

1002 version Version, 

1003 privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, 

1004 privateKey PrivateKey, 

1005 attributes [0] Attributes OPTIONAL, 

1006 ..., 

1007 [[2: publicKey [1] PublicKey OPTIONAL ]], 

1008 ... 

1009 } 

1010 

1011 The `attributes` and `publicKey` fields are completely ignored; errors 

1012 in them will not be detected. 

1013 

1014 :param string: binary string with DER-encoded private ECDSA key 

1015 :type string: :term:`bytes-like object` 

1016 :param valid_curve_encodings: list of allowed encoding formats 

1017 for curve parameters. By default (``None``) all are supported: 

1018 ``named_curve`` and ``explicit``. 

1019 Ignored for EdDSA. 

1020 :type valid_curve_encodings: :term:`set-like object` 

1021 

1022 :raises MalformedPointError: if the length of encoding doesn't match 

1023 the provided curve or the encoded values is too large 

1024 :raises RuntimeError: if the generation of public key from private 

1025 key failed 

1026 :raises UnexpectedDER: if the encoding of the DER file is incorrect 

1027 

1028 :return: Initialised SigningKey object 

1029 :rtype: SigningKey 

1030 """ 

1031 s = normalise_bytes(string) 

1032 curve = None 

1033 

1034 s, empty = der.remove_sequence(s) 

1035 if empty != b(""): 

1036 raise der.UnexpectedDER( 

1037 "trailing junk after DER privkey: %s" % binascii.hexlify(empty) 

1038 ) 

1039 

1040 version, s = der.remove_integer(s) 

1041 

1042 # At this point, PKCS #8 has a sequence containing the algorithm 

1043 # identifier and the curve identifier. The ssleay format instead has 

1044 # an octet string containing the key data, so this is how we can 

1045 # distinguish the two formats. 

1046 if der.is_sequence(s): 

1047 if version not in (0, 1): 

1048 raise der.UnexpectedDER( 

1049 "expected version '0' or '1' at start of privkey, got %d" 

1050 % version 

1051 ) 

1052 

1053 sequence, s = der.remove_sequence(s) 

1054 algorithm_oid, algorithm_identifier = der.remove_object(sequence) 

1055 

1056 if algorithm_oid in (Ed25519.oid, Ed448.oid): 

1057 if algorithm_identifier: 

1058 raise der.UnexpectedDER( 

1059 "Non NULL parameters for a EdDSA key" 

1060 ) 

1061 key_str_der, s = der.remove_octet_string(s) 

1062 

1063 # As RFC5958 describe, there are may be optional Attributes 

1064 # and Publickey. Don't raise error if something after 

1065 # Privatekey 

1066 

1067 # TODO parse attributes or validate publickey 

1068 # if s: 

1069 # raise der.UnexpectedDER( 

1070 # "trailing junk inside the privateKey" 

1071 # ) 

1072 key_str, s = der.remove_octet_string(key_str_der) 

1073 if s: 

1074 raise der.UnexpectedDER( 

1075 "trailing junk after the encoded private key" 

1076 ) 

1077 

1078 if algorithm_oid == Ed25519.oid: 

1079 curve = Ed25519 

1080 else: 

1081 assert algorithm_oid == Ed448.oid 

1082 curve = Ed448 

1083 

1084 return cls.from_string(key_str, curve, None) 

1085 

1086 if algorithm_oid not in (oid_ecPublicKey, oid_ecDH, oid_ecMQV): 

1087 raise der.UnexpectedDER( 

1088 "unexpected algorithm identifier '%s'" % (algorithm_oid,) 

1089 ) 

1090 

1091 curve = Curve.from_der(algorithm_identifier, valid_curve_encodings) 

1092 

1093 if empty != b"": 

1094 raise der.UnexpectedDER( 

1095 "unexpected data after algorithm identifier: %s" 

1096 % binascii.hexlify(empty) 

1097 ) 

1098 

1099 # Up next is an octet string containing an ECPrivateKey. Ignore 

1100 # the optional "attributes" and "publicKey" fields that come after. 

1101 s, _ = der.remove_octet_string(s) 

1102 

1103 # Unpack the ECPrivateKey to get to the key data octet string, 

1104 # and rejoin the ssleay parsing path. 

1105 s, empty = der.remove_sequence(s) 

1106 if empty != b(""): 

1107 raise der.UnexpectedDER( 

1108 "trailing junk after DER privkey: %s" 

1109 % binascii.hexlify(empty) 

1110 ) 

1111 

1112 version, s = der.remove_integer(s) 

1113 

1114 # The version of the ECPrivateKey must be 1. 

1115 if version != 1: 

1116 raise der.UnexpectedDER( 

1117 "expected version '1' at start of DER privkey, got %d" 

1118 % version 

1119 ) 

1120 

1121 privkey_str, s = der.remove_octet_string(s) 

1122 

1123 if not curve: 

1124 tag, curve_oid_str, s = der.remove_constructed(s) 

1125 if tag != 0: 

1126 raise der.UnexpectedDER( 

1127 "expected tag 0 in DER privkey, got %d" % tag 

1128 ) 

1129 curve = Curve.from_der(curve_oid_str, valid_curve_encodings) 

1130 

1131 # we don't actually care about the following fields 

1132 # 

1133 # tag, pubkey_bitstring, s = der.remove_constructed(s) 

1134 # if tag != 1: 

1135 # raise der.UnexpectedDER("expected tag 1 in DER privkey, got %d" 

1136 # % tag) 

1137 # pubkey_str = der.remove_bitstring(pubkey_bitstring, 0) 

1138 # if empty != "": 

1139 # raise der.UnexpectedDER("trailing junk after DER privkey " 

1140 # "pubkeystr: %s" 

1141 # % binascii.hexlify(empty)) 

1142 

1143 # our from_string method likes fixed-length privkey strings 

1144 if len(privkey_str) < curve.baselen: 

1145 privkey_str = ( 

1146 b("\x00") * (curve.baselen - len(privkey_str)) + privkey_str 

1147 ) 

1148 return cls.from_string(privkey_str, curve, hashfunc) 

1149 

1150 def to_string(self): 

1151 """ 

1152 Convert the private key to :term:`raw encoding`. 

1153 

1154 Note: while the method is named "to_string", its name comes from 

1155 Python 2 days, when binary and character strings used the same type. 

1156 The type used in Python 3 is `bytes`. 

1157 

1158 :return: raw encoding of private key 

1159 :rtype: bytes 

1160 """ 

1161 if isinstance(self.curve.curve, CurveEdTw): 

1162 return bytes(self.privkey.private_key) 

1163 secexp = self.privkey.secret_multiplier 

1164 s = number_to_string(secexp, self.privkey.order) 

1165 return s 

1166 

1167 def to_pem( 

1168 self, 

1169 point_encoding="uncompressed", 

1170 format="ssleay", 

1171 curve_parameters_encoding=None, 

1172 ): 

1173 """ 

1174 Convert the private key to the :term:`PEM` format. 

1175 

1176 See :func:`~SigningKey.from_pem` method for format description. 

1177 

1178 Only the named curve format is supported. 

1179 The public key will be included in generated string. 

1180 

1181 The PEM header will specify ``BEGIN EC PRIVATE KEY`` or 

1182 ``BEGIN PRIVATE KEY``, depending on the desired format. 

1183 

1184 :param str point_encoding: format to use for encoding public point 

1185 :param str format: either ``ssleay`` (default) or ``pkcs8`` 

1186 :param str curve_parameters_encoding: format of encoded curve 

1187 parameters, default depends on the curve, if the curve has 

1188 an associated OID, ``named_curve`` format will be used, 

1189 if no OID is associated with the curve, the fallback of 

1190 ``explicit`` parameters will be used. 

1191 

1192 :return: PEM encoded private key 

1193 :rtype: bytes 

1194 

1195 .. warning:: The PEM is encoded to US-ASCII, it needs to be 

1196 re-encoded if the system is incompatible (e.g. uses UTF-16) 

1197 """ 

1198 # TODO: "BEGIN ECPARAMETERS" 

1199 assert format in ("ssleay", "pkcs8") 

1200 header = "EC PRIVATE KEY" if format == "ssleay" else "PRIVATE KEY" 

1201 return der.topem( 

1202 self.to_der(point_encoding, format, curve_parameters_encoding), 

1203 header, 

1204 ) 

1205 

1206 def _encode_eddsa(self): 

1207 """Create a PKCS#8 encoding of EdDSA keys.""" 

1208 ec_private_key = der.encode_octet_string(self.to_string()) 

1209 return der.encode_sequence( 

1210 der.encode_integer(0), 

1211 der.encode_sequence(der.encode_oid(*self.curve.oid)), 

1212 der.encode_octet_string(ec_private_key), 

1213 ) 

1214 

1215 def to_der( 

1216 self, 

1217 point_encoding="uncompressed", 

1218 format="ssleay", 

1219 curve_parameters_encoding=None, 

1220 ): 

1221 """ 

1222 Convert the private key to the :term:`DER` format. 

1223 

1224 See :func:`~SigningKey.from_der` method for format specification. 

1225 

1226 Only the named curve format is supported. 

1227 The public key will be included in the generated string. 

1228 

1229 :param str point_encoding: format to use for encoding public point 

1230 Ignored for EdDSA 

1231 :param str format: either ``ssleay`` (default) or ``pkcs8``. 

1232 EdDSA keys require ``pkcs8``. 

1233 :param str curve_parameters_encoding: format of encoded curve 

1234 parameters, default depends on the curve, if the curve has 

1235 an associated OID, ``named_curve`` format will be used, 

1236 if no OID is associated with the curve, the fallback of 

1237 ``explicit`` parameters will be used. 

1238 Ignored for EdDSA. 

1239 

1240 :return: DER encoded private key 

1241 :rtype: bytes 

1242 """ 

1243 # SEQ([int(1), octetstring(privkey),cont[0], oid(secp224r1), 

1244 # cont[1],bitstring]) 

1245 if point_encoding == "raw": 

1246 raise ValueError("raw encoding not allowed in DER") 

1247 assert format in ("ssleay", "pkcs8") 

1248 if isinstance(self.curve.curve, CurveEdTw): 

1249 if format != "pkcs8": 

1250 raise ValueError("Only PKCS#8 format supported for EdDSA keys") 

1251 return self._encode_eddsa() 

1252 encoded_vk = self.get_verifying_key().to_string(point_encoding) 

1253 priv_key_elems = [ 

1254 der.encode_integer(1), 

1255 der.encode_octet_string(self.to_string()), 

1256 ] 

1257 if format == "ssleay": 

1258 priv_key_elems.append( 

1259 der.encode_constructed( 

1260 0, self.curve.to_der(curve_parameters_encoding) 

1261 ) 

1262 ) 

1263 # the 0 in encode_bitstring specifies the number of unused bits 

1264 # in the `encoded_vk` string 

1265 priv_key_elems.append( 

1266 der.encode_constructed(1, der.encode_bitstring(encoded_vk, 0)) 

1267 ) 

1268 ec_private_key = der.encode_sequence(*priv_key_elems) 

1269 

1270 if format == "ssleay": 

1271 return ec_private_key 

1272 else: 

1273 return der.encode_sequence( 

1274 # version = 1 means the public key is not present in the 

1275 # top-level structure. 

1276 der.encode_integer(1), 

1277 der.encode_sequence( 

1278 der.encode_oid(*oid_ecPublicKey), 

1279 self.curve.to_der(curve_parameters_encoding), 

1280 ), 

1281 der.encode_octet_string(ec_private_key), 

1282 ) 

1283 

1284 def get_verifying_key(self): 

1285 """ 

1286 Return the VerifyingKey associated with this private key. 

1287 

1288 Equivalent to reading the `verifying_key` field of an instance. 

1289 

1290 :return: a public key that can be used to verify the signatures made 

1291 with this SigningKey 

1292 :rtype: VerifyingKey 

1293 """ 

1294 return self.verifying_key 

1295 

1296 def sign_deterministic( 

1297 self, 

1298 data, 

1299 hashfunc=None, 

1300 sigencode=sigencode_string, 

1301 extra_entropy=b"", 

1302 ): 

1303 """ 

1304 Create signature over data. 

1305 

1306 For Weierstrass curves it uses the deterministic RFC6979 algorithm. 

1307 For Edwards curves it uses the standard EdDSA algorithm. 

1308 

1309 For ECDSA the data will be hashed using the `hashfunc` function before 

1310 signing. 

1311 For EdDSA the data will be hashed with the hash associated with the 

1312 curve (SHA-512 for Ed25519 and SHAKE-256 for Ed448). 

1313 

1314 This is the recommended method for performing signatures when hashing 

1315 of data is necessary. 

1316 

1317 :param data: data to be hashed and computed signature over 

1318 :type data: :term:`bytes-like object` 

1319 :param hashfunc: hash function to use for computing the signature, 

1320 if unspecified, the default hash function selected during 

1321 object initialisation will be used (see 

1322 `VerifyingKey.default_hashfunc`). The object needs to implement 

1323 the same interface as hashlib.sha1. 

1324 Ignored with EdDSA. 

1325 :type hashfunc: callable 

1326 :param sigencode: function used to encode the signature. 

1327 The function needs to accept three parameters: the two integers 

1328 that are the signature and the order of the curve over which the 

1329 signature was computed. It needs to return an encoded signature. 

1330 See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der` 

1331 as examples of such functions. 

1332 Ignored with EdDSA. 

1333 :type sigencode: callable 

1334 :param extra_entropy: additional data that will be fed into the random 

1335 number generator used in the RFC6979 process. Entirely optional. 

1336 Ignored with EdDSA. 

1337 :type extra_entropy: :term:`bytes-like object` 

1338 

1339 :return: encoded signature over `data` 

1340 :rtype: bytes or sigencode function dependent type 

1341 """ 

1342 hashfunc = hashfunc or self.default_hashfunc 

1343 data = normalise_bytes(data) 

1344 

1345 if isinstance(self.curve.curve, CurveEdTw): 

1346 return self.privkey.sign(data) 

1347 

1348 extra_entropy = normalise_bytes(extra_entropy) 

1349 digest = hashfunc(data).digest() 

1350 

1351 return self.sign_digest_deterministic( 

1352 digest, 

1353 hashfunc=hashfunc, 

1354 sigencode=sigencode, 

1355 extra_entropy=extra_entropy, 

1356 allow_truncate=True, 

1357 ) 

1358 

1359 def sign_digest_deterministic( 

1360 self, 

1361 digest, 

1362 hashfunc=None, 

1363 sigencode=sigencode_string, 

1364 extra_entropy=b"", 

1365 allow_truncate=False, 

1366 ): 

1367 """ 

1368 Create signature for digest using the deterministic RFC6979 algorithm. 

1369 

1370 `digest` should be the output of cryptographically secure hash function 

1371 like SHA256 or SHA-3-256. 

1372 

1373 This is the recommended method for performing signatures when no 

1374 hashing of data is necessary. 

1375 

1376 :param digest: hash of data that will be signed 

1377 :type digest: :term:`bytes-like object` 

1378 :param hashfunc: hash function to use for computing the random "k" 

1379 value from RFC6979 process, 

1380 if unspecified, the default hash function selected during 

1381 object initialisation will be used (see 

1382 :attr:`.VerifyingKey.default_hashfunc`). The object needs to 

1383 implement 

1384 the same interface as :func:`~hashlib.sha1` from :py:mod:`hashlib`. 

1385 :type hashfunc: callable 

1386 :param sigencode: function used to encode the signature. 

1387 The function needs to accept three parameters: the two integers 

1388 that are the signature and the order of the curve over which the 

1389 signature was computed. It needs to return an encoded signature. 

1390 See :func:`~ecdsa.util.sigencode_string` and 

1391 :func:`~ecdsa.util.sigencode_der` 

1392 as examples of such functions. 

1393 :type sigencode: callable 

1394 :param extra_entropy: additional data that will be fed into the random 

1395 number generator used in the RFC6979 process. Entirely optional. 

1396 :type extra_entropy: :term:`bytes-like object` 

1397 :param bool allow_truncate: if True, the provided digest can have 

1398 bigger bit-size than the order of the curve, the extra bits (at 

1399 the end of the digest) will be truncated. Use it when signing 

1400 SHA-384 output using NIST256p or in similar situations. 

1401 

1402 :return: encoded signature for the `digest` hash 

1403 :rtype: bytes or sigencode function dependent type 

1404 """ 

1405 if isinstance(self.curve.curve, CurveEdTw): 

1406 raise ValueError("Method unsupported for Edwards curves") 

1407 secexp = self.privkey.secret_multiplier 

1408 hashfunc = hashfunc or self.default_hashfunc 

1409 digest = normalise_bytes(digest) 

1410 extra_entropy = normalise_bytes(extra_entropy) 

1411 

1412 def simple_r_s(r, s, order): 

1413 return r, s, order 

1414 

1415 retry_gen = 0 

1416 while True: 

1417 k = rfc6979.generate_k( 

1418 self.curve.generator.order(), 

1419 secexp, 

1420 hashfunc, 

1421 digest, 

1422 retry_gen=retry_gen, 

1423 extra_entropy=extra_entropy, 

1424 ) 

1425 try: 

1426 r, s, order = self.sign_digest( 

1427 digest, 

1428 sigencode=simple_r_s, 

1429 k=k, 

1430 allow_truncate=allow_truncate, 

1431 ) 

1432 break 

1433 except RSZeroError: 

1434 retry_gen += 1 

1435 

1436 return sigencode(r, s, order) 

1437 

1438 def sign( 

1439 self, 

1440 data, 

1441 entropy=None, 

1442 hashfunc=None, 

1443 sigencode=sigencode_string, 

1444 k=None, 

1445 allow_truncate=True, 

1446 ): 

1447 """ 

1448 Create signature over data. 

1449 

1450 Uses the probabilistic ECDSA algorithm for Weierstrass curves 

1451 (NIST256p, etc.) and the deterministic EdDSA algorithm for the 

1452 Edwards curves (Ed25519, Ed448). 

1453 

1454 This method uses the standard ECDSA algorithm that requires a 

1455 cryptographically secure random number generator. 

1456 

1457 It's recommended to use the :func:`~SigningKey.sign_deterministic` 

1458 method instead of this one. 

1459 

1460 :param data: data that will be hashed for signing 

1461 :type data: :term:`bytes-like object` 

1462 :param callable entropy: randomness source, :func:`os.urandom` by 

1463 default. Ignored with EdDSA. 

1464 :param hashfunc: hash function to use for hashing the provided 

1465 ``data``. 

1466 If unspecified the default hash function selected during 

1467 object initialisation will be used (see 

1468 :attr:`.VerifyingKey.default_hashfunc`). 

1469 Should behave like :func:`~hashlib.sha1` from :py:mod:`hashlib`. 

1470 The output length of the 

1471 hash (in bytes) must not be longer than the length of the curve 

1472 order (rounded up to the nearest byte), so using SHA256 with 

1473 NIST256p is ok, but SHA256 with NIST192p is not. (In the 2**-96ish 

1474 unlikely event of a hash output larger than the curve order, the 

1475 hash will effectively be wrapped mod n). 

1476 If you want to explicitly allow use of large hashes with small 

1477 curves set the ``allow_truncate`` to ``True``. 

1478 Use ``hashfunc=hashlib.sha1`` to match openssl's 

1479 ``-ecdsa-with-SHA1`` mode, 

1480 or ``hashfunc=hashlib.sha256`` for openssl-1.0.0's 

1481 ``-ecdsa-with-SHA256``. 

1482 Ignored for EdDSA 

1483 :type hashfunc: callable 

1484 :param sigencode: function used to encode the signature. 

1485 The function needs to accept three parameters: the two integers 

1486 that are the signature and the order of the curve over which the 

1487 signature was computed. It needs to return an encoded signature. 

1488 See :func:`~ecdsa.util.sigencode_string` and 

1489 :func:`~ecdsa.util.sigencode_der` 

1490 as examples of such functions. 

1491 Ignored for EdDSA 

1492 :type sigencode: callable 

1493 :param int k: a pre-selected nonce for calculating the signature. 

1494 In typical use cases, it should be set to None (the default) to 

1495 allow its generation from an entropy source. 

1496 Ignored for EdDSA. 

1497 :param bool allow_truncate: if ``True``, the provided digest can have 

1498 bigger bit-size than the order of the curve, the extra bits (at 

1499 the end of the digest) will be truncated. Use it when signing 

1500 SHA-384 output using NIST256p or in similar situations. True by 

1501 default. 

1502 Ignored for EdDSA. 

1503 

1504 :raises RSZeroError: in the unlikely event when *r* parameter or 

1505 *s* parameter of the created signature is equal 0, as that would 

1506 leak the key. Caller should try a better entropy source, retry with 

1507 different ``k``, or use the 

1508 :func:`~SigningKey.sign_deterministic` in such case. 

1509 

1510 :return: encoded signature of the hash of `data` 

1511 :rtype: bytes or sigencode function dependent type 

1512 """ 

1513 hashfunc = hashfunc or self.default_hashfunc 

1514 data = normalise_bytes(data) 

1515 if isinstance(self.curve.curve, CurveEdTw): 

1516 return self.sign_deterministic(data) 

1517 h = hashfunc(data).digest() 

1518 return self.sign_digest(h, entropy, sigencode, k, allow_truncate) 

1519 

1520 def sign_digest( 

1521 self, 

1522 digest, 

1523 entropy=None, 

1524 sigencode=sigencode_string, 

1525 k=None, 

1526 allow_truncate=False, 

1527 ): 

1528 """ 

1529 Create signature over digest using the probabilistic ECDSA algorithm. 

1530 

1531 This method uses the standard ECDSA algorithm that requires a 

1532 cryptographically secure random number generator. 

1533 

1534 This method does not hash the input. 

1535 

1536 It's recommended to use the 

1537 :func:`~SigningKey.sign_digest_deterministic` method 

1538 instead of this one. 

1539 

1540 :param digest: hash value that will be signed 

1541 :type digest: :term:`bytes-like object` 

1542 :param callable entropy: randomness source, os.urandom by default 

1543 :param sigencode: function used to encode the signature. 

1544 The function needs to accept three parameters: the two integers 

1545 that are the signature and the order of the curve over which the 

1546 signature was computed. It needs to return an encoded signature. 

1547 See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der` 

1548 as examples of such functions. 

1549 :type sigencode: callable 

1550 :param int k: a pre-selected nonce for calculating the signature. 

1551 In typical use cases, it should be set to None (the default) to 

1552 allow its generation from an entropy source. 

1553 :param bool allow_truncate: if True, the provided digest can have 

1554 bigger bit-size than the order of the curve, the extra bits (at 

1555 the end of the digest) will be truncated. Use it when signing 

1556 SHA-384 output using NIST256p or in similar situations. 

1557 

1558 :raises RSZeroError: in the unlikely event when "r" parameter or 

1559 "s" parameter of the created signature is equal 0, as that would 

1560 leak the key. Caller should try a better entropy source, retry with 

1561 different 'k', or use the 

1562 :func:`~SigningKey.sign_digest_deterministic` in such case. 

1563 

1564 :return: encoded signature for the `digest` hash 

1565 :rtype: bytes or sigencode function dependent type 

1566 """ 

1567 if isinstance(self.curve.curve, CurveEdTw): 

1568 raise ValueError("Method unsupported for Edwards curves") 

1569 digest = normalise_bytes(digest) 

1570 number = _truncate_and_convert_digest( 

1571 digest, 

1572 self.curve, 

1573 allow_truncate, 

1574 ) 

1575 r, s = self.sign_number(number, entropy, k) 

1576 return sigencode(r, s, self.privkey.order) 

1577 

1578 def sign_number(self, number, entropy=None, k=None): 

1579 """ 

1580 Sign an integer directly. 

1581 

1582 Note, this is a low level method, usually you will want to use 

1583 :func:`~SigningKey.sign_deterministic` or 

1584 :func:`~SigningKey.sign_digest_deterministic`. 

1585 

1586 :param int number: number to sign using the probabilistic ECDSA 

1587 algorithm. 

1588 :param callable entropy: entropy source, os.urandom by default 

1589 :param int k: pre-selected nonce for signature operation. If unset 

1590 it will be selected at random using the entropy source. 

1591 

1592 :raises RSZeroError: in the unlikely event when "r" parameter or 

1593 "s" parameter of the created signature is equal 0, as that would 

1594 leak the key. Caller should try a better entropy source, retry with 

1595 different 'k', or use the 

1596 :func:`~SigningKey.sign_digest_deterministic` in such case. 

1597 

1598 :return: the "r" and "s" parameters of the signature 

1599 :rtype: tuple of ints 

1600 """ 

1601 if isinstance(self.curve.curve, CurveEdTw): 

1602 raise ValueError("Method unsupported for Edwards curves") 

1603 order = self.privkey.order 

1604 

1605 if k is not None: 

1606 _k = k 

1607 else: 

1608 _k = randrange(order, entropy) 

1609 

1610 assert 1 <= _k < order 

1611 sig = self.privkey.sign(number, _k) 

1612 return sig.r, sig.s