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

382 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-07 06:31 +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, ssh 

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 to_ssh(self): 

618 """ 

619 Convert the public key to the SSH format. 

620 

621 :return: SSH encoding of the public key 

622 :rtype: bytes 

623 """ 

624 return ssh.serialize_public( 

625 self.curve.name, 

626 self.to_string(), 

627 ) 

628 

629 def verify( 

630 self, 

631 signature, 

632 data, 

633 hashfunc=None, 

634 sigdecode=sigdecode_string, 

635 allow_truncate=True, 

636 ): 

637 """ 

638 Verify a signature made over provided data. 

639 

640 Will hash `data` to verify the signature. 

641 

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

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

644 :func:`ecdsa.util.sigdecode_der` 

645 as the `sigdecode` parameter. 

646 

647 :param signature: encoding of the signature 

648 :type signature: sigdecode method dependent 

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

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

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

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

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

654 :type hashfunc: callable 

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

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

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

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

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

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

661 :type sigdecode: callable 

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

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

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

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

666 True. 

667 

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

669 

670 :return: True if the verification was successful 

671 :rtype: bool 

672 """ 

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

674 # it, the decoders will do that 

675 data = normalise_bytes(data) 

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

677 signature = normalise_bytes(signature) 

678 try: 

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

680 except (ValueError, MalformedPointError) as e: 

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

682 

683 hashfunc = hashfunc or self.default_hashfunc 

684 digest = hashfunc(data).digest() 

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

686 

687 def verify_digest( 

688 self, 

689 signature, 

690 digest, 

691 sigdecode=sigdecode_string, 

692 allow_truncate=False, 

693 ): 

694 """ 

695 Verify a signature made over provided hash value. 

696 

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

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

699 :func:`ecdsa.util.sigdecode_der` 

700 as the `sigdecode` parameter. 

701 

702 :param signature: encoding of the signature 

703 :type signature: sigdecode method dependent 

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

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

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

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

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

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

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

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

712 :type sigdecode: callable 

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

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

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

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

717 

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

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

720 associated with this VerifyingKey and allow_truncate was not set 

721 

722 :return: True if the verification was successful 

723 :rtype: bool 

724 """ 

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

726 # it, the decoders will do that 

727 digest = normalise_bytes(digest) 

728 number = _truncate_and_convert_digest( 

729 digest, 

730 self.curve, 

731 allow_truncate, 

732 ) 

733 

734 try: 

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

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

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

738 sig = ecdsa.Signature(r, s) 

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

740 return True 

741 raise BadSignatureError("Signature verification failed") 

742 

743 

744class SigningKey(object): 

745 """ 

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

747 

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

749 cryptographic operations will take place 

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

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

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

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

754 associated with this private key 

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

756 """ 

757 

758 def __init__(self, _error__please_use_generate=None): 

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

760 if not _error__please_use_generate: 

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

762 self.curve = None 

763 self.default_hashfunc = None 

764 self.baselen = None 

765 self.verifying_key = None 

766 self.privkey = None 

767 

768 def __eq__(self, other): 

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

770 if isinstance(other, SigningKey): 

771 return ( 

772 self.curve == other.curve 

773 and self.verifying_key == other.verifying_key 

774 and self.privkey == other.privkey 

775 ) 

776 return NotImplemented 

777 

778 def __ne__(self, other): 

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

780 return not self == other 

781 

782 @classmethod 

783 def _twisted_edwards_keygen(cls, curve, entropy): 

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

785 if not entropy: 

786 entropy = os.urandom 

787 random = entropy(curve.baselen) 

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

789 public_key = private_key.public_key() 

790 

791 verifying_key = VerifyingKey.from_string( 

792 public_key.public_key(), curve 

793 ) 

794 

795 self = cls(_error__please_use_generate=True) 

796 self.curve = curve 

797 self.default_hashfunc = None 

798 self.baselen = curve.baselen 

799 self.privkey = private_key 

800 self.verifying_key = verifying_key 

801 return self 

802 

803 @classmethod 

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

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

806 secexp = randrange(curve.order, entropy) 

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

808 

809 @classmethod 

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

811 """ 

812 Generate a random private key. 

813 

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

815 to NIST192p 

816 :type curve: ~ecdsa.curves.Curve 

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

818 should provide cryptographically secure random numbers if the keys 

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

820 :type entropy: callable 

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

822 signing, needs to implement the same interface 

823 as hashlib.sha1 

824 :type hashfunc: callable 

825 

826 :return: Initialised SigningKey object 

827 :rtype: SigningKey 

828 """ 

829 if isinstance(curve.curve, CurveEdTw): 

830 return cls._twisted_edwards_keygen(curve, entropy) 

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

832 

833 @classmethod 

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

835 """ 

836 Create a private key from a random integer. 

837 

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

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

840 

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

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

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

844 :type curve: ~ecdsa.curves.Curve 

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

846 signing, needs to implement the same interface 

847 as hashlib.sha1 

848 :type hashfunc: callable 

849 

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

851 or too small for the curve selected 

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

853 key failed 

854 

855 :return: Initialised SigningKey object 

856 :rtype: SigningKey 

857 """ 

858 if isinstance(curve.curve, CurveEdTw): 

859 raise ValueError( 

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

861 "(exponent) directly" 

862 ) 

863 self = cls(_error__please_use_generate=True) 

864 self.curve = curve 

865 self.default_hashfunc = hashfunc 

866 self.baselen = curve.baselen 

867 n = curve.order 

868 if not 1 <= secexp < n: 

869 raise MalformedPointError( 

870 "Invalid value for secexp, expected integer " 

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

872 ) 

873 pubkey_point = curve.generator * secexp 

874 if hasattr(pubkey_point, "scale"): 

875 pubkey_point = pubkey_point.scale() 

876 self.verifying_key = VerifyingKey.from_public_point( 

877 pubkey_point, curve, hashfunc, False 

878 ) 

879 pubkey = self.verifying_key.pubkey 

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

881 self.privkey.order = n 

882 return self 

883 

884 @classmethod 

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

886 """ 

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

888 

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

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

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

892 

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

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

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

896 :type curve: ~ecdsa.curves.Curve 

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

898 signing, needs to implement the same interface 

899 as hashlib.sha1 

900 :type hashfunc: callable 

901 

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

903 the provided curve or the encoded values is too large 

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

905 key failed 

906 

907 :return: Initialised SigningKey object 

908 :rtype: SigningKey 

909 """ 

910 string = normalise_bytes(string) 

911 

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

913 raise MalformedPointError( 

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

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

916 ) 

917 if isinstance(curve.curve, CurveEdTw): 

918 self = cls(_error__please_use_generate=True) 

919 self.curve = curve 

920 self.default_hashfunc = None # Ignored for EdDSA 

921 self.baselen = curve.baselen 

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

923 self.verifying_key = VerifyingKey.from_string( 

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

925 ) 

926 return self 

927 secexp = string_to_number(string) 

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

929 

930 @classmethod 

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

932 """ 

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

934 

935 The PEM formats supported are the un-encrypted RFC5915 

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

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

938 

939 The legacy format files have the header with the string 

940 ``BEGIN EC PRIVATE KEY``. 

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

942 Encrypted files (ones that include the string 

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

944 right after the PEM header) are not supported. 

945 

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

947 this files. 

948 

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

950 :type string: str 

951 :param valid_curve_encodings: list of allowed encoding formats 

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

953 ``named_curve`` and ``explicit``. 

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

955 

956 

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

958 the provided curve or the encoded values is too large 

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

960 key failed 

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

962 

963 :return: Initialised SigningKey object 

964 :rtype: SigningKey 

965 """ 

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

967 string = string.encode() 

968 

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

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

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

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

973 if private_key_index == -1: 

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

975 

976 return cls.from_der( 

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

978 hashfunc, 

979 valid_curve_encodings, 

980 ) 

981 

982 @classmethod 

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

984 """ 

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

986 

987 The DER formats supported are the un-encrypted RFC5915 

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

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

990 

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

992 in RFC5915:: 

993 

994 ECPrivateKey ::= SEQUENCE { 

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

996 privateKey OCTET STRING, 

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

998 publicKey [1] BIT STRING OPTIONAL 

999 } 

1000 

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

1002 be undetected). 

1003 

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

1005 curve and the explicit encoding of curve parameters. 

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

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

1008 is part of the PrivateKeyAlgorithmIdentifier. 

1009 

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

1011 field within a larger structure:: 

1012 

1013 OneAsymmetricKey ::= SEQUENCE { 

1014 version Version, 

1015 privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, 

1016 privateKey PrivateKey, 

1017 attributes [0] Attributes OPTIONAL, 

1018 ..., 

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

1020 ... 

1021 } 

1022 

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

1024 in them will not be detected. 

1025 

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

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

1028 :param valid_curve_encodings: list of allowed encoding formats 

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

1030 ``named_curve`` and ``explicit``. 

1031 Ignored for EdDSA. 

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

1033 

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

1035 the provided curve or the encoded values is too large 

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

1037 key failed 

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

1039 

1040 :return: Initialised SigningKey object 

1041 :rtype: SigningKey 

1042 """ 

1043 s = normalise_bytes(string) 

1044 curve = None 

1045 

1046 s, empty = der.remove_sequence(s) 

1047 if empty != b(""): 

1048 raise der.UnexpectedDER( 

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

1050 ) 

1051 

1052 version, s = der.remove_integer(s) 

1053 

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

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

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

1057 # distinguish the two formats. 

1058 if der.is_sequence(s): 

1059 if version not in (0, 1): 

1060 raise der.UnexpectedDER( 

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

1062 % version 

1063 ) 

1064 

1065 sequence, s = der.remove_sequence(s) 

1066 algorithm_oid, algorithm_identifier = der.remove_object(sequence) 

1067 

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

1069 if algorithm_identifier: 

1070 raise der.UnexpectedDER( 

1071 "Non NULL parameters for a EdDSA key" 

1072 ) 

1073 key_str_der, s = der.remove_octet_string(s) 

1074 

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

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

1077 # Privatekey 

1078 

1079 # TODO parse attributes or validate publickey 

1080 # if s: 

1081 # raise der.UnexpectedDER( 

1082 # "trailing junk inside the privateKey" 

1083 # ) 

1084 key_str, s = der.remove_octet_string(key_str_der) 

1085 if s: 

1086 raise der.UnexpectedDER( 

1087 "trailing junk after the encoded private key" 

1088 ) 

1089 

1090 if algorithm_oid == Ed25519.oid: 

1091 curve = Ed25519 

1092 else: 

1093 assert algorithm_oid == Ed448.oid 

1094 curve = Ed448 

1095 

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

1097 

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

1099 raise der.UnexpectedDER( 

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

1101 ) 

1102 

1103 curve = Curve.from_der(algorithm_identifier, valid_curve_encodings) 

1104 

1105 if empty != b"": 

1106 raise der.UnexpectedDER( 

1107 "unexpected data after algorithm identifier: %s" 

1108 % binascii.hexlify(empty) 

1109 ) 

1110 

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

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

1113 s, _ = der.remove_octet_string(s) 

1114 

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

1116 # and rejoin the ssleay parsing path. 

1117 s, empty = der.remove_sequence(s) 

1118 if empty != b(""): 

1119 raise der.UnexpectedDER( 

1120 "trailing junk after DER privkey: %s" 

1121 % binascii.hexlify(empty) 

1122 ) 

1123 

1124 version, s = der.remove_integer(s) 

1125 

1126 # The version of the ECPrivateKey must be 1. 

1127 if version != 1: 

1128 raise der.UnexpectedDER( 

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

1130 % version 

1131 ) 

1132 

1133 privkey_str, s = der.remove_octet_string(s) 

1134 

1135 if not curve: 

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

1137 if tag != 0: 

1138 raise der.UnexpectedDER( 

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

1140 ) 

1141 curve = Curve.from_der(curve_oid_str, valid_curve_encodings) 

1142 

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

1144 # 

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

1146 # if tag != 1: 

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

1148 # % tag) 

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

1150 # if empty != "": 

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

1152 # "pubkeystr: %s" 

1153 # % binascii.hexlify(empty)) 

1154 

1155 # our from_string method likes fixed-length privkey strings 

1156 if len(privkey_str) < curve.baselen: 

1157 privkey_str = ( 

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

1159 ) 

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

1161 

1162 def to_string(self): 

1163 """ 

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

1165 

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

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

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

1169 

1170 :return: raw encoding of private key 

1171 :rtype: bytes 

1172 """ 

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

1174 return bytes(self.privkey.private_key) 

1175 secexp = self.privkey.secret_multiplier 

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

1177 return s 

1178 

1179 def to_pem( 

1180 self, 

1181 point_encoding="uncompressed", 

1182 format="ssleay", 

1183 curve_parameters_encoding=None, 

1184 ): 

1185 """ 

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

1187 

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

1189 

1190 Only the named curve format is supported. 

1191 The public key will be included in generated string. 

1192 

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

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

1195 

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

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

1198 :param str curve_parameters_encoding: format of encoded curve 

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

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

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

1202 ``explicit`` parameters will be used. 

1203 

1204 :return: PEM encoded private key 

1205 :rtype: bytes 

1206 

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

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

1209 """ 

1210 # TODO: "BEGIN ECPARAMETERS" 

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

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

1213 return der.topem( 

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

1215 header, 

1216 ) 

1217 

1218 def _encode_eddsa(self): 

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

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

1221 return der.encode_sequence( 

1222 der.encode_integer(0), 

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

1224 der.encode_octet_string(ec_private_key), 

1225 ) 

1226 

1227 def to_der( 

1228 self, 

1229 point_encoding="uncompressed", 

1230 format="ssleay", 

1231 curve_parameters_encoding=None, 

1232 ): 

1233 """ 

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

1235 

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

1237 

1238 Only the named curve format is supported. 

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

1240 

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

1242 Ignored for EdDSA 

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

1244 EdDSA keys require ``pkcs8``. 

1245 :param str curve_parameters_encoding: format of encoded curve 

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

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

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

1249 ``explicit`` parameters will be used. 

1250 Ignored for EdDSA. 

1251 

1252 :return: DER encoded private key 

1253 :rtype: bytes 

1254 """ 

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

1256 # cont[1],bitstring]) 

1257 if point_encoding == "raw": 

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

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

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

1261 if format != "pkcs8": 

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

1263 return self._encode_eddsa() 

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

1265 priv_key_elems = [ 

1266 der.encode_integer(1), 

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

1268 ] 

1269 if format == "ssleay": 

1270 priv_key_elems.append( 

1271 der.encode_constructed( 

1272 0, self.curve.to_der(curve_parameters_encoding) 

1273 ) 

1274 ) 

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

1276 # in the `encoded_vk` string 

1277 priv_key_elems.append( 

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

1279 ) 

1280 ec_private_key = der.encode_sequence(*priv_key_elems) 

1281 

1282 if format == "ssleay": 

1283 return ec_private_key 

1284 else: 

1285 return der.encode_sequence( 

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

1287 # top-level structure. 

1288 der.encode_integer(1), 

1289 der.encode_sequence( 

1290 der.encode_oid(*oid_ecPublicKey), 

1291 self.curve.to_der(curve_parameters_encoding), 

1292 ), 

1293 der.encode_octet_string(ec_private_key), 

1294 ) 

1295 

1296 def to_ssh(self): 

1297 """ 

1298 Convert the private key to the SSH format. 

1299 

1300 :return: SSH encoded private key 

1301 :rtype: bytes 

1302 """ 

1303 return ssh.serialize_private( 

1304 self.curve.name, 

1305 self.verifying_key.to_string(), 

1306 self.to_string(), 

1307 ) 

1308 

1309 def get_verifying_key(self): 

1310 """ 

1311 Return the VerifyingKey associated with this private key. 

1312 

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

1314 

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

1316 with this SigningKey 

1317 :rtype: VerifyingKey 

1318 """ 

1319 return self.verifying_key 

1320 

1321 def sign_deterministic( 

1322 self, 

1323 data, 

1324 hashfunc=None, 

1325 sigencode=sigencode_string, 

1326 extra_entropy=b"", 

1327 ): 

1328 """ 

1329 Create signature over data. 

1330 

1331 For Weierstrass curves it uses the deterministic RFC6979 algorithm. 

1332 For Edwards curves it uses the standard EdDSA algorithm. 

1333 

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

1335 signing. 

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

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

1338 

1339 This is the recommended method for performing signatures when hashing 

1340 of data is necessary. 

1341 

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

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

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

1345 if unspecified, the default hash function selected during 

1346 object initialisation will be used (see 

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

1348 the same interface as hashlib.sha1. 

1349 Ignored with EdDSA. 

1350 :type hashfunc: callable 

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

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

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

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

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

1356 as examples of such functions. 

1357 Ignored with EdDSA. 

1358 :type sigencode: callable 

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

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

1361 Ignored with EdDSA. 

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

1363 

1364 :return: encoded signature over `data` 

1365 :rtype: bytes or sigencode function dependent type 

1366 """ 

1367 hashfunc = hashfunc or self.default_hashfunc 

1368 data = normalise_bytes(data) 

1369 

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

1371 return self.privkey.sign(data) 

1372 

1373 extra_entropy = normalise_bytes(extra_entropy) 

1374 digest = hashfunc(data).digest() 

1375 

1376 return self.sign_digest_deterministic( 

1377 digest, 

1378 hashfunc=hashfunc, 

1379 sigencode=sigencode, 

1380 extra_entropy=extra_entropy, 

1381 allow_truncate=True, 

1382 ) 

1383 

1384 def sign_digest_deterministic( 

1385 self, 

1386 digest, 

1387 hashfunc=None, 

1388 sigencode=sigencode_string, 

1389 extra_entropy=b"", 

1390 allow_truncate=False, 

1391 ): 

1392 """ 

1393 Create signature for digest using the deterministic RFC6979 algorithm. 

1394 

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

1396 like SHA256 or SHA-3-256. 

1397 

1398 This is the recommended method for performing signatures when no 

1399 hashing of data is necessary. 

1400 

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

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

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

1404 value from RFC6979 process, 

1405 if unspecified, the default hash function selected during 

1406 object initialisation will be used (see 

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

1408 implement 

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

1410 :type hashfunc: callable 

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

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

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

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

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

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

1417 as examples of such functions. 

1418 :type sigencode: callable 

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

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

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

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

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

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

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

1426 

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

1428 :rtype: bytes or sigencode function dependent type 

1429 """ 

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

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

1432 secexp = self.privkey.secret_multiplier 

1433 hashfunc = hashfunc or self.default_hashfunc 

1434 digest = normalise_bytes(digest) 

1435 extra_entropy = normalise_bytes(extra_entropy) 

1436 

1437 def simple_r_s(r, s, order): 

1438 return r, s, order 

1439 

1440 retry_gen = 0 

1441 while True: 

1442 k = rfc6979.generate_k( 

1443 self.curve.generator.order(), 

1444 secexp, 

1445 hashfunc, 

1446 digest, 

1447 retry_gen=retry_gen, 

1448 extra_entropy=extra_entropy, 

1449 ) 

1450 try: 

1451 r, s, order = self.sign_digest( 

1452 digest, 

1453 sigencode=simple_r_s, 

1454 k=k, 

1455 allow_truncate=allow_truncate, 

1456 ) 

1457 break 

1458 except RSZeroError: 

1459 retry_gen += 1 

1460 

1461 return sigencode(r, s, order) 

1462 

1463 def sign( 

1464 self, 

1465 data, 

1466 entropy=None, 

1467 hashfunc=None, 

1468 sigencode=sigencode_string, 

1469 k=None, 

1470 allow_truncate=True, 

1471 ): 

1472 """ 

1473 Create signature over data. 

1474 

1475 Uses the probabilistic ECDSA algorithm for Weierstrass curves 

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

1477 Edwards curves (Ed25519, Ed448). 

1478 

1479 This method uses the standard ECDSA algorithm that requires a 

1480 cryptographically secure random number generator. 

1481 

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

1483 method instead of this one. 

1484 

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

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

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

1488 default. Ignored with EdDSA. 

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

1490 ``data``. 

1491 If unspecified the default hash function selected during 

1492 object initialisation will be used (see 

1493 :attr:`.VerifyingKey.default_hashfunc`). 

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

1495 The output length of the 

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

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

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

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

1500 hash will effectively be wrapped mod n). 

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

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

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

1504 ``-ecdsa-with-SHA1`` mode, 

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

1506 ``-ecdsa-with-SHA256``. 

1507 Ignored for EdDSA 

1508 :type hashfunc: callable 

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

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

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

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

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

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

1515 as examples of such functions. 

1516 Ignored for EdDSA 

1517 :type sigencode: callable 

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

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

1520 allow its generation from an entropy source. 

1521 Ignored for EdDSA. 

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

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

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

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

1526 default. 

1527 Ignored for EdDSA. 

1528 

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

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

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

1532 different ``k``, or use the 

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

1534 

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

1536 :rtype: bytes or sigencode function dependent type 

1537 """ 

1538 hashfunc = hashfunc or self.default_hashfunc 

1539 data = normalise_bytes(data) 

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

1541 return self.sign_deterministic(data) 

1542 h = hashfunc(data).digest() 

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

1544 

1545 def sign_digest( 

1546 self, 

1547 digest, 

1548 entropy=None, 

1549 sigencode=sigencode_string, 

1550 k=None, 

1551 allow_truncate=False, 

1552 ): 

1553 """ 

1554 Create signature over digest using the probabilistic ECDSA algorithm. 

1555 

1556 This method uses the standard ECDSA algorithm that requires a 

1557 cryptographically secure random number generator. 

1558 

1559 This method does not hash the input. 

1560 

1561 It's recommended to use the 

1562 :func:`~SigningKey.sign_digest_deterministic` method 

1563 instead of this one. 

1564 

1565 :param digest: hash value that will be signed 

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

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

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

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

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

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

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

1573 as examples of such functions. 

1574 :type sigencode: callable 

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

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

1577 allow its generation from an entropy source. 

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

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

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

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

1582 

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

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

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

1586 different 'k', or use the 

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

1588 

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

1590 :rtype: bytes or sigencode function dependent type 

1591 """ 

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

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

1594 digest = normalise_bytes(digest) 

1595 number = _truncate_and_convert_digest( 

1596 digest, 

1597 self.curve, 

1598 allow_truncate, 

1599 ) 

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

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

1602 

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

1604 """ 

1605 Sign an integer directly. 

1606 

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

1608 :func:`~SigningKey.sign_deterministic` or 

1609 :func:`~SigningKey.sign_digest_deterministic`. 

1610 

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

1612 algorithm. 

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

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

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

1616 

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

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

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

1620 different 'k', or use the 

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

1622 

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

1624 :rtype: tuple of ints 

1625 """ 

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

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

1628 order = self.privkey.order 

1629 

1630 if k is not None: 

1631 _k = k 

1632 else: 

1633 _k = randrange(order, entropy) 

1634 

1635 assert 1 <= _k < order 

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

1637 return sig.r, sig.s