1 |
pygcrypt uses libgcrypt which provides support for ripemd160, whirlpool, |
2 |
SHA3, plus some algorithms not provided by any other library. |
3 |
--- |
4 |
pym/portage/checksum.py | 38 ++++++++++++++++++++++++++++++++++++++ |
5 |
1 file changed, 38 insertions(+) |
6 |
|
7 |
diff --git a/pym/portage/checksum.py b/pym/portage/checksum.py |
8 |
index 2c482f5e7..92b41b133 100644 |
9 |
--- a/pym/portage/checksum.py |
10 |
+++ b/pym/portage/checksum.py |
11 |
@@ -135,6 +135,44 @@ if "SHA3_256" not in hashfunc_map or "SHA3_512" not in hashfunc_map: |
12 |
pass |
13 |
|
14 |
|
15 |
+# Support pygcrypt as fallback using optimized routines from libgcrypt |
16 |
+# (GnuPG). |
17 |
+gcrypt_algos = frozenset(('RMD160', 'WHIRLPOOL', 'SHA3_256', 'SHA3_512')) |
18 |
+if gcrypt_algos.difference(hashfunc_map): |
19 |
+ try: |
20 |
+ import binascii |
21 |
+ import pygcrypt.hashcontext |
22 |
+ |
23 |
+ class GCryptHashWrapper(object): |
24 |
+ def __init__(self, algo): |
25 |
+ self._obj = pygcrypt.hashcontext.HashContext(algo=algo) |
26 |
+ |
27 |
+ def update(self, data): |
28 |
+ self._obj.write(data) |
29 |
+ |
30 |
+ def hexdigest(self): |
31 |
+ return binascii.b2a_hex(self._obj.read()).decode() |
32 |
+ |
33 |
+ name_mapping = { |
34 |
+ 'RMD160': 'ripemd160', |
35 |
+ 'WHIRLPOOL': 'whirlpool', |
36 |
+ 'SHA3_256': 'sha3-256', |
37 |
+ 'SHA3_512': 'sha3-512', |
38 |
+ } |
39 |
+ |
40 |
+ for local_name, gcry_name in name_mapping.items(): |
41 |
+ try: |
42 |
+ pygcrypt.hashcontext.HashContext(algo=gcry_name) |
43 |
+ except Exception: # yes, it throws Exception... |
44 |
+ pass |
45 |
+ else: |
46 |
+ _generate_hash_function(local_name, |
47 |
+ functools.partial(GCryptHashWrapper, gcry_name), |
48 |
+ origin="pygcrypt") |
49 |
+ except ImportError: |
50 |
+ pass |
51 |
+ |
52 |
+ |
53 |
# Use pycrypto when available, prefer it over the internal fallbacks |
54 |
# Check for 'new' attributes, since they can be missing if the module |
55 |
# is broken somehow. |
56 |
-- |
57 |
2.12.0 |