URI: 
       tchange prng, add warning against encrypting multiple secrets (#4649) - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 2a5f108d4ab2145c5784934063293bc2decce67a
   DIR parent bc6010303a0010c9c027b99d8c65c68481d2c585
  HTML Author: tiagotrs <tiago@posteo.de>
       Date:   Wed, 22 Aug 2018 22:25:12 +0200
       
       change prng, add warning against encrypting multiple secrets (#4649)
       
       * substitute python prng generator with hmac_drbg
       
       * add warning, change version
       
       * brick cards version 0
       
       * separate python-drbg module, include tests and license
       
       * import to match PEP 8
       
       * fix line break, minor changes in wording
       
       * fixes noise_seed formatting errors
       
       * fix import, include license exclude tests drbg module
       
       Diffstat:
         A electrum/plugins/revealer/hmac_drb… |      51 +++++++++++++++++++++++++++++++
         M electrum/plugins/revealer/qt.py     |      39 ++++++++++++++++++++++---------
       
       2 files changed, 79 insertions(+), 11 deletions(-)
       ---
   DIR diff --git a/electrum/plugins/revealer/hmac_drbg.py b/electrum/plugins/revealer/hmac_drbg.py
       t@@ -0,0 +1,51 @@
       +'''
       +Copyright (c) 2014 David Lazar <lazard@mit.edu>
       +
       +Permission is hereby granted, free of charge, to any person obtaining a copy
       +of this software and associated documentation files (the "Software"), to deal
       +in the Software without restriction, including without limitation the rights
       +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       +copies of the Software, and to permit persons to whom the Software is
       +furnished to do so, subject to the following conditions:
       +
       +The above copyright notice and this permission notice shall be included in
       +all copies or substantial portions of the Software.
       +
       +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       +THE SOFTWARE.
       +'''
       +
       +import hashlib
       +import hmac
       +
       +class DRBG(object):
       +    def __init__(self, seed):
       +        self.key = b'\x00' * 64
       +        self.val = b'\x01' * 64
       +        self.reseed(seed)
       +
       +    def hmac(self, key, val):
       +        return hmac.new(key, val, hashlib.sha512).digest()
       +
       +    def reseed(self, data=b''):
       +        self.key = self.hmac(self.key, self.val + b'\x00' + data)
       +        self.val = self.hmac(self.key, self.val)
       +
       +        if data:
       +            self.key = self.hmac(self.key, self.val + b'\x01' + data)
       +            self.val = self.hmac(self.key, self.val)
       +
       +    def generate(self, n):
       +        xs = b''
       +        while len(xs) < n:
       +            self.val = self.hmac(self.key, self.val)
       +            xs += self.val
       +
       +        self.reseed()
       +
       +        return xs[:n]
   DIR diff --git a/electrum/plugins/revealer/qt.py b/electrum/plugins/revealer/qt.py
       t@@ -22,16 +22,17 @@ import qrcode
        import traceback
        from hashlib import sha256
        from decimal import Decimal
       +import binascii
        
        from PyQt5.QtPrintSupport import QPrinter
        
        from electrum.plugin import BasePlugin, hook
        from electrum.i18n import _
        from electrum.util import to_bytes, make_dir
       -
        from electrum.gui.qt.util import *
        from electrum.gui.qt.qrtextedit import ScanQRTextEdit
        
       +from .hmac_drbg import DRBG
        
        class Plugin(BasePlugin):
        
       t@@ -47,7 +48,7 @@ class Plugin(BasePlugin):
                self.calibration_h = self.config.get('calibration_h')
                self.calibration_v = self.config.get('calibration_v')
        
       -        self.version = '0'
       +        self.version = '1'
                self.size = (159, 97)
                self.f_size = QSize(1014*2, 642*2)
                self.abstand_h = 21
       t@@ -130,7 +131,7 @@ class Plugin(BasePlugin):
                s = self.get_noise()
                b = self.is_noise(s)
                if b:
       -            self.noise_seed = s[:-3]
       +            self.noise_seed = s[1:-3]
                    self.user_input = True
                self.next_button.setEnabled(b)
        
       t@@ -155,6 +156,9 @@ class Plugin(BasePlugin):
                        else:
                            return False
                else:
       +
       +            if (len(txt)>0 and txt[0]=='0'):
       +                self.d.show_message(''.join(["<b>",_("Warning: "), "</b>", _("Revealers starting with 0 had a vulnerability and are not supported.")]))
                    self.user_input = False
                    return False
        
       t@@ -211,12 +215,12 @@ class Plugin(BasePlugin):
                grid = QGridLayout()
                self.vbox.addLayout(grid)
        
       -        cprint = QPushButton(_("Generate encrypted seed PDF"))
       +        cprint = QPushButton(_("Generate encrypted seed backup"))
                cprint.clicked.connect(partial(self.seed_img, True))
                self.vbox.addWidget(cprint)
                self.vbox.addSpacing(14)
        
       -        self.vbox.addWidget(WWLabel(_("and/or type any secret below:")))
       +        self.vbox.addWidget(WWLabel(_("OR type any secret below:")))
                self.text = ScanQRTextEdit()
                self.text.setTabChangesFocus(True)
                self.text.setMaximumHeight(70)
       t@@ -231,12 +235,19 @@ class Plugin(BasePlugin):
                self.vbox.addWidget(self.max_chars)
                self.max_chars.setVisible(False)
        
       -        self.ctext = QPushButton(_("Generate custom secret encrypted PDF"))
       +        self.ctext = QPushButton(_("Generate custom secret encrypted backup"))
                self.ctext.clicked.connect(self.t)
        
                self.vbox.addWidget(self.ctext)
                self.ctext.setEnabled(False)
        
       +        self.vbox.addSpacing(11)
       +        self.vbox.addWidget(
       +                            QLabel(''.join(["<b>" + _("WARNING") + "</b>: " + _("Revealer is a one-time-pad and should be used only once."), '<br/>',
       +                            _("Multiple secrets encrypted for the same Revealer can be attacked."), '<br/>',
       +                            ])))
       +        self.vbox.addSpacing(11)
       +
                self.vbox.addSpacing(21)
                self.vbox.addLayout(Buttons(CloseButton(d)))
                return bool(d.exec_())
       t@@ -305,21 +316,27 @@ class Plugin(BasePlugin):
        
                if(self.noise_seed == False):
                    self.noise_seed = random.SystemRandom().getrandbits(128)
       -            self.hex_noise = format(self.noise_seed, '02x')
       +            self.hex_noise = format(self.noise_seed, '032x')
                    self.hex_noise = self.version + str(self.hex_noise)
        
                if (self.user_input == True):
                    self.noise_seed = int(self.noise_seed, 16)
       -            self.hex_noise = self.version + str(format(self.noise_seed, '02x'))
       -
       +            self.hex_noise = self.version + str(format(self.noise_seed, '032x'))
        
                self.code_id = self.code_hashid(self.hex_noise)
                self.hex_noise = ' '.join(self.hex_noise[i:i+4] for i in range(0,len(self.hex_noise),4))
       -        random.seed(self.noise_seed)
        
       +        entropy = binascii.unhexlify(str(format(self.noise_seed, '032x')))
       +        code_id = binascii.unhexlify(self.version + self.code_id)
       +
       +        drbg = DRBG(entropy + code_id)
       +        noise_array=bin(int.from_bytes(drbg.generate(1929), 'big'))[2:]
       +
       +        i=0
                for x in range(w):
                    for y in range(h):
       -                rawnoise.setPixel(x,y,random.randint(0, 1))
       +                rawnoise.setPixel(x,y,int(noise_array[i]))
       +                i+=1
        
                self.rawnoise = rawnoise
                if create_revealer==True: