aboutsummaryrefslogtreecommitdiff
path: root/frozen_deps/ecdsa/ecdsa.py
diff options
context:
space:
mode:
Diffstat (limited to 'frozen_deps/ecdsa/ecdsa.py')
-rw-r--r--frozen_deps/ecdsa/ecdsa.py426
1 files changed, 383 insertions, 43 deletions
diff --git a/frozen_deps/ecdsa/ecdsa.py b/frozen_deps/ecdsa/ecdsa.py
index d785a45..9284ace 100644
--- a/frozen_deps/ecdsa/ecdsa.py
+++ b/frozen_deps/ecdsa/ecdsa.py
@@ -1,59 +1,71 @@
#! /usr/bin/env python
"""
-Implementation of Elliptic-Curve Digital Signatures.
+Low level implementation of Elliptic-Curve Digital Signatures.
+
+.. note ::
+ You're most likely looking for the :py:class:`~ecdsa.keys` module.
+ This is a low-level implementation of the ECDSA that operates on
+ integers, not byte strings.
+
+NOTE: This a low level implementation of ECDSA, for normal applications
+you should be looking at the keys.py module.
Classes and methods for elliptic-curve signatures:
private keys, public keys, signatures,
-NIST prime-modulus curves with modulus lengths of
-192, 224, 256, 384, and 521 bits.
+and definitions of prime-modulus curves.
Example:
- # (In real-life applications, you would probably want to
- # protect against defects in SystemRandom.)
- from random import SystemRandom
- randrange = SystemRandom().randrange
+.. code-block:: python
- # Generate a public/private key pair using the NIST Curve P-192:
+ # (In real-life applications, you would probably want to
+ # protect against defects in SystemRandom.)
+ from random import SystemRandom
+ randrange = SystemRandom().randrange
- g = generator_192
- n = g.order()
- secret = randrange( 1, n )
- pubkey = Public_key( g, g * secret )
- privkey = Private_key( pubkey, secret )
+ # Generate a public/private key pair using the NIST Curve P-192:
- # Signing a hash value:
+ g = generator_192
+ n = g.order()
+ secret = randrange( 1, n )
+ pubkey = Public_key( g, g * secret )
+ privkey = Private_key( pubkey, secret )
- hash = randrange( 1, n )
- signature = privkey.sign( hash, randrange( 1, n ) )
+ # Signing a hash value:
- # Verifying a signature for a hash value:
+ hash = randrange( 1, n )
+ signature = privkey.sign( hash, randrange( 1, n ) )
- if pubkey.verifies( hash, signature ):
- print_("Demo verification succeeded.")
- else:
- print_("*** Demo verification failed.")
+ # Verifying a signature for a hash value:
- # Verification fails if the hash value is modified:
+ if pubkey.verifies( hash, signature ):
+ print_("Demo verification succeeded.")
+ else:
+ print_("*** Demo verification failed.")
- if pubkey.verifies( hash-1, signature ):
- print_("**** Demo verification failed to reject tampered hash.")
- else:
- print_("Demo verification correctly rejected tampered hash.")
+ # Verification fails if the hash value is modified:
-Version of 2009.05.16.
+ if pubkey.verifies( hash-1, signature ):
+ print_("**** Demo verification failed to reject tampered hash.")
+ else:
+ print_("Demo verification correctly rejected tampered hash.")
Revision history:
2005.12.31 - Initial version.
+
2008.11.25 - Substantial revisions introducing new classes.
+
2009.05.16 - Warn against using random.randrange in real applications.
+
2009.05.17 - Use random.SystemRandom by default.
-Written in 2005 by Peter Pearson and placed in the public domain.
+Originally written in 2005 by Peter Pearson and placed in the public domain,
+modified as part of the python-ecdsa package.
"""
-from six import int2byte, b
+import warnings
+from six import int2byte
from . import ellipticcurve
from . import numbertheory
from .util import bit_length
@@ -69,16 +81,26 @@ class InvalidPointError(RuntimeError):
class Signature(object):
- """ECDSA signature."""
+ """
+ ECDSA signature.
+
+ :ivar int r: the ``r`` element of the ECDSA signature
+ :ivar int s: the ``s`` element of the ECDSA signature
+ """
def __init__(self, r, s):
self.r = r
self.s = s
def recover_public_keys(self, hash, generator):
- """Returns two public keys for which the signature is valid
- hash is signed hash
- generator is the used generator of the signature
+ """
+ Returns two public keys for which the signature is valid
+
+ :param int hash: signed hash
+ :param AbstractPoint generator: is the generator used in creation
+ of the signature
+ :rtype: tuple(Public_key, Public_key)
+ :return: a pair of public keys that can validate the signature
"""
curve = generator.curve()
n = generator.order()
@@ -118,7 +140,7 @@ class Public_key(object):
:param bool verify: if True check if point is valid point on curve
:raises InvalidPointError: if the point parameters are invalid or
- point does not lie on the curve
+ point does not lay on the curve
"""
self.curve = generator.curve()
@@ -131,7 +153,7 @@ class Public_key(object):
"The public point has x or y out of range."
)
if verify and not self.curve.contains_point(point.x(), point.y()):
- raise InvalidPointError("Point does not lie on the curve")
+ raise InvalidPointError("Point does not lay on the curve")
if not n:
raise InvalidPointError("Generator point must have order.")
# for curve parameters with base point with cofactor 1, all points
@@ -145,11 +167,20 @@ class Public_key(object):
raise InvalidPointError("Generator point order is bad.")
def __eq__(self, other):
+ """Return True if the keys are identical, False otherwise.
+
+ Note: for comparison, only placement on the same curve and point
+ equality is considered, use of the same generator point is not
+ considered.
+ """
if isinstance(other, Public_key):
- """Return True if the points are identical, False otherwise."""
return self.curve == other.curve and self.point == other.point
return NotImplemented
+ def __ne__(self, other):
+ """Return False if the keys are identical, True otherwise."""
+ return not self == other
+
def verifies(self, hash, signature):
"""Verify that signature is a valid signature of hash.
Return True if the signature is valid.
@@ -188,14 +219,18 @@ class Private_key(object):
self.secret_multiplier = secret_multiplier
def __eq__(self, other):
+ """Return True if the points are identical, False otherwise."""
if isinstance(other, Private_key):
- """Return True if the points are identical, False otherwise."""
return (
self.public_key == other.public_key
and self.secret_multiplier == other.secret_multiplier
)
return NotImplemented
+ def __ne__(self, other):
+ """Return False if the points are identical, True otherwise."""
+ return not self == other
+
def sign(self, hash, random_k):
"""Return a signature for the provided hash, using the provided
random nonce. It is absolutely vital that random_k be an unpredictable
@@ -235,11 +270,17 @@ class Private_key(object):
return Signature(r, s)
-def int_to_string(x):
+def int_to_string(x): # pragma: no cover
"""Convert integer x into a string of bytes, as per X9.62."""
+ # deprecated in 0.19
+ warnings.warn(
+ "Function is unused in library code. If you use this code, "
+ "change to util.string_to_number.",
+ DeprecationWarning,
+ )
assert x >= 0
if x == 0:
- return b("\0")
+ return b"\0"
result = []
while x:
ordinal = x & 0xFF
@@ -247,11 +288,17 @@ def int_to_string(x):
x >>= 8
result.reverse()
- return b("").join(result)
+ return b"".join(result)
-def string_to_int(s):
+def string_to_int(s): # pragma: no cover
"""Convert a string of bytes into an integer, as per X9.62."""
+ # deprecated in 0.19
+ warnings.warn(
+ "Function is unused in library code. If you use this code, "
+ "change to util.number_to_string.",
+ DeprecationWarning,
+ )
result = 0
for c in s:
if not isinstance(c, int):
@@ -260,9 +307,16 @@ def string_to_int(s):
return result
-def digest_integer(m):
+def digest_integer(m): # pragma: no cover
"""Convert an integer into a string of bytes, compute
- its SHA-1 hash, and convert the result to an integer."""
+ its SHA-1 hash, and convert the result to an integer."""
+ # deprecated in 0.19
+ warnings.warn(
+ "Function is unused in library code. If you use this code, "
+ "change to a one-liner with util.number_to_string and "
+ "util.string_to_number methods.",
+ DeprecationWarning,
+ )
#
# I don't expect this function to be used much. I wrote
# it in order to be able to duplicate the examples
@@ -294,6 +348,77 @@ def point_is_valid(generator, x, y):
return True
+# secp112r1 curve
+_p = int(remove_whitespace("DB7C 2ABF62E3 5E668076 BEAD208B"), 16)
+# s = 00F50B02 8E4D696E 67687561 51752904 72783FB1
+_a = int(remove_whitespace("DB7C 2ABF62E3 5E668076 BEAD2088"), 16)
+_b = int(remove_whitespace("659E F8BA0439 16EEDE89 11702B22"), 16)
+_Gx = int(remove_whitespace("09487239 995A5EE7 6B55F9C2 F098"), 16)
+_Gy = int(remove_whitespace("A89C E5AF8724 C0A23E0E 0FF77500"), 16)
+_r = int(remove_whitespace("DB7C 2ABF62E3 5E7628DF AC6561C5"), 16)
+_h = 1
+curve_112r1 = ellipticcurve.CurveFp(_p, _a, _b, _h)
+generator_112r1 = ellipticcurve.PointJacobi(
+ curve_112r1, _Gx, _Gy, 1, _r, generator=True
+)
+
+
+# secp112r2 curve
+_p = int(remove_whitespace("DB7C 2ABF62E3 5E668076 BEAD208B"), 16)
+# s = 022757A1 114D69E 67687561 51755316 C05E0BD4
+_a = int(remove_whitespace("6127 C24C05F3 8A0AAAF6 5C0EF02C"), 16)
+_b = int(remove_whitespace("51DE F1815DB5 ED74FCC3 4C85D709"), 16)
+_Gx = int(remove_whitespace("4BA30AB5 E892B4E1 649DD092 8643"), 16)
+_Gy = int(remove_whitespace("ADCD 46F5882E 3747DEF3 6E956E97"), 16)
+_r = int(remove_whitespace("36DF 0AAFD8B8 D7597CA1 0520D04B"), 16)
+_h = 4
+curve_112r2 = ellipticcurve.CurveFp(_p, _a, _b, _h)
+generator_112r2 = ellipticcurve.PointJacobi(
+ curve_112r2, _Gx, _Gy, 1, _r, generator=True
+)
+
+
+# secp128r1 curve
+_p = int(remove_whitespace("FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF"), 16)
+# S = 000E0D4D 69E6768 75615175 0CC03A44 73D03679
+# a and b are mod p, so a is equal to p-3, or simply -3
+# _a = -3
+_b = int(remove_whitespace("E87579C1 1079F43D D824993C 2CEE5ED3"), 16)
+_Gx = int(remove_whitespace("161FF752 8B899B2D 0C28607C A52C5B86"), 16)
+_Gy = int(remove_whitespace("CF5AC839 5BAFEB13 C02DA292 DDED7A83"), 16)
+_r = int(remove_whitespace("FFFFFFFE 00000000 75A30D1B 9038A115"), 16)
+_h = 1
+curve_128r1 = ellipticcurve.CurveFp(_p, -3, _b, _h)
+generator_128r1 = ellipticcurve.PointJacobi(
+ curve_128r1, _Gx, _Gy, 1, _r, generator=True
+)
+
+
+# secp160r1
+_p = int(remove_whitespace("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 7FFFFFFF"), 16)
+# S = 1053CDE4 2C14D696 E6768756 1517533B F3F83345
+# a and b are mod p, so a is equal to p-3, or simply -3
+# _a = -3
+_b = int(remove_whitespace("1C97BEFC 54BD7A8B 65ACF89F 81D4D4AD C565FA45"), 16)
+_Gx = int(
+ remove_whitespace("4A96B568 8EF57328 46646989 68C38BB9 13CBFC82"),
+ 16,
+)
+_Gy = int(
+ remove_whitespace("23A62855 3168947D 59DCC912 04235137 7AC5FB32"),
+ 16,
+)
+_r = int(
+ remove_whitespace("01 00000000 00000000 0001F4C8 F927AED3 CA752257"),
+ 16,
+)
+_h = 1
+curve_160r1 = ellipticcurve.CurveFp(_p, -3, _b, _h)
+generator_160r1 = ellipticcurve.PointJacobi(
+ curve_160r1, _Gx, _Gy, 1, _r, generator=True
+)
+
+
# NIST Curve P-192:
_p = 6277101735386680763835789423207666416083908700390324961279
_r = 6277101735386680763835789423176059013767194773182842284081
@@ -549,6 +674,18 @@ generator_brainpoolp160r1 = ellipticcurve.PointJacobi(
curve_brainpoolp160r1, _Gx, _Gy, 1, _q, generator=True
)
+# Brainpool P-160-t1
+_a = 0xE95E4A5F737059DC60DFC7AD95B3D8139515620C
+_b = 0x7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380
+# _z = 0x24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B
+_Gx = 0xB199B13B9B34EFC1397E64BAEB05ACC265FF2378
+_Gy = 0xADD6718B7C7C1961F0991B842443772152C9E0AD
+_q = 0xE95E4A5F737059DC60DF5991D45029409E60FC09
+curve_brainpoolp160t1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp160t1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp160t1, _Gx, _Gy, 1, _q, generator=True
+)
+
# Brainpool P-192-r1
_a = 0x6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF
_b = 0x469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9
@@ -562,6 +699,19 @@ generator_brainpoolp192r1 = ellipticcurve.PointJacobi(
curve_brainpoolp192r1, _Gx, _Gy, 1, _q, generator=True
)
+# Brainpool P-192-t1
+_a = 0xC302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294
+_b = 0x13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79
+# _z = 0x1B6F5CC8DB4DC7AF19458A9CB80DC2295E5EB9C3732104CB
+_Gx = 0x3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129
+_Gy = 0x097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9
+_q = 0xC302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1
+
+curve_brainpoolp192t1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp192t1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp192t1, _Gx, _Gy, 1, _q, generator=True
+)
+
# Brainpool P-224-r1
_a = 0x68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43
_b = 0x2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B
@@ -575,6 +725,19 @@ generator_brainpoolp224r1 = ellipticcurve.PointJacobi(
curve_brainpoolp224r1, _Gx, _Gy, 1, _q, generator=True
)
+# Brainpool P-224-t1
+_a = 0xD7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC
+_b = 0x4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D
+# _z = 0x2DF271E14427A346910CF7A2E6CFA7B3F484E5C2CCE1C8B730E28B3F
+_Gx = 0x6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580
+_Gy = 0x0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C
+_q = 0xD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F
+
+curve_brainpoolp224t1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp224t1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp224t1, _Gx, _Gy, 1, _q, generator=True
+)
+
# Brainpool P-256-r1
_a = 0x7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9
_b = 0x26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6
@@ -588,6 +751,19 @@ generator_brainpoolp256r1 = ellipticcurve.PointJacobi(
curve_brainpoolp256r1, _Gx, _Gy, 1, _q, generator=True
)
+# Brainpool P-256-t1
+_a = 0xA9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374
+_b = 0x662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04
+# _z = 0x3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0
+_Gx = 0xA3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4
+_Gy = 0x2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE
+_q = 0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7
+
+curve_brainpoolp256t1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp256t1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp256t1, _Gx, _Gy, 1, _q, generator=True
+)
+
# Brainpool P-320-r1
_a = int(
remove_whitespace(
@@ -643,6 +819,61 @@ generator_brainpoolp320r1 = ellipticcurve.PointJacobi(
curve_brainpoolp320r1, _Gx, _Gy, 1, _q, generator=True
)
+# Brainpool P-320-t1
+_a = int(
+ remove_whitespace(
+ """
+ D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC
+ 28FCD412B1F1B32E24"""
+ ),
+ 16,
+)
+_b = int(
+ remove_whitespace(
+ """
+ A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547
+ CEB5B4FEF422340353"""
+ ),
+ 16,
+)
+# _z = int(
+# remove_whitespace(
+# """
+# 15F75CAF668077F7E85B42EB01F0A81FF56ECD6191D55CB82B7D861458A18F
+# EFC3E5AB7496F3C7B1"""
+# ),
+# 16,
+# )
+_Gx = int(
+ remove_whitespace(
+ """
+ 925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136F
+ FF3357F624A21BED52"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE7
+ 1B1B9BC0455FB0D2C3"""
+ ),
+ 16,
+)
+_q = int(
+ remove_whitespace(
+ """
+ D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658
+ E98691555B44C59311"""
+ ),
+ 16,
+)
+
+curve_brainpoolp320t1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp320t1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp320t1, _Gx, _Gy, 1, _q, generator=True
+)
+
# Brainpool P-384-r1
_a = int(
remove_whitespace(
@@ -698,6 +929,60 @@ generator_brainpoolp384r1 = ellipticcurve.PointJacobi(
curve_brainpoolp384r1, _Gx, _Gy, 1, _q, generator=True
)
+_a = int(
+ remove_whitespace(
+ """
+ 8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB711
+ 23ACD3A729901D1A71874700133107EC50"""
+ ),
+ 16,
+)
+_b = int(
+ remove_whitespace(
+ """
+ 7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE
+ 1D2074AA263B88805CED70355A33B471EE"""
+ ),
+ 16,
+)
+# _z = int(
+# remove_whitespace(
+# """
+# 41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE
+# 97D2D63DBC87BCCDDCCC5DA39E8589291C"""
+# ),
+# 16,
+# )
+_Gx = int(
+ remove_whitespace(
+ """
+ 18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AAB
+ FFC4FF191B946A5F54D8D0AA2F418808CC"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CC
+ FE469408584DC2B2912675BF5B9E582928"""
+ ),
+ 16,
+)
+_q = int(
+ remove_whitespace(
+ """
+ 8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425
+ A7CF3AB6AF6B7FC3103B883202E9046565"""
+ ),
+ 16,
+)
+
+curve_brainpoolp384t1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp384t1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp384t1, _Gx, _Gy, 1, _q, generator=True
+)
+
# Brainpool P-512-r1
_a = int(
remove_whitespace(
@@ -752,3 +1037,58 @@ curve_brainpoolp512r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
generator_brainpoolp512r1 = ellipticcurve.PointJacobi(
curve_brainpoolp512r1, _Gx, _Gy, 1, _q, generator=True
)
+
+# Brainpool P-512-t1
+_a = int(
+ remove_whitespace(
+ """
+ AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308
+ 717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0"""
+ ),
+ 16,
+)
+_b = int(
+ remove_whitespace(
+ """
+ 7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36
+ A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E"""
+ ),
+ 16,
+)
+# _z = int(
+# remove_whitespace(
+# """
+# 12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B
+# 64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB"""
+# ),
+# 16,
+# )
+_Gx = int(
+ remove_whitespace(
+ """
+ 640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C031
+ 3D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA"""
+ ),
+ 16,
+)
+_Gy = int(
+ remove_whitespace(
+ """
+ 5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CE
+ E9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332"""
+ ),
+ 16,
+)
+_q = int(
+ remove_whitespace(
+ """
+ AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308
+ 70553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069"""
+ ),
+ 16,
+)
+
+curve_brainpoolp512t1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
+generator_brainpoolp512t1 = ellipticcurve.PointJacobi(
+ curve_brainpoolp512t1, _Gx, _Gy, 1, _q, generator=True
+)