def HMACSha256(keyBin, msgBin):
    from uhashlib import sha256
    block_size = 64  # SHA-256 blocks size

    trans_5C = bytearray(256)
    for x in range(len(trans_5C)):
        trans_5C[x] = x ^ 0x5C

    trans_36 = bytearray(256)
    for x in range(len(trans_36)):
        trans_36[x] = x ^ 0x36

    def translate(d, t):
        res = bytearray(len(d))
        for x in range(len(d)):
            res[x] = t[d[x]]
        return res

    keyBin = keyBin + chr(0) * (block_size - len(keyBin))

    inner = sha256()
    inner.update(translate(keyBin, trans_36))
    inner.update(msgBin)
    inner = inner.digest()

    outer = sha256()
    outer.update(translate(keyBin, trans_5C))
    outer.update(inner)

    return outer.digest()
def hmac_sha256(key_K, data):
    if len(key_K) > 64:
        raise ValueError('The key must be <= 64 bytes in length')
    padded_K = key_K + b'\x00' * (64 - len(key_K))
    ipad = b'\x36' * 64
    opad = b'\x5c' * 64
    h_inner = sha256(xor(padded_K, ipad))
    h_inner.update(data)
    h_outer = sha256(xor(padded_K, opad))
    h_outer.update(h_inner.digest())
    return h_outer.digest()
Beispiel #3
0
    def __init__(self, key, msg=None):
        """Create a new HMAC object.

        key:       key for the keyed hash object.
        msg:       Initial input for the hash, if provided.

        Note: key and msg must be a bytes or bytearray objects.
        """

        if not isinstance(key, (bytes, bytearray)):
            raise TypeError(
                "key: expected bytes or bytearray, but got %r" % type(key).__name__
            )

        self.digest_cons = lambda d=b"": _hashlib.sha256(d)

        self.outer = self.digest_cons()
        self.inner = self.digest_cons()
        blocksize = self.blocksize

        if len(key) > blocksize:
            key = self.digest_cons(key).digest()

        key = key + bytes(blocksize - len(key))
        self.outer.update(translate(key, trans_5C))
        self.inner.update(translate(key, trans_36))
        if msg is not None:
            self.update(msg)
Beispiel #4
0
 def encode_key(cls, prevout):
     # hash up the txid and output number, truncate, and encode as base64
     # - truncating at (mod3) bytes so no padding on b64 output
     # - expects a COutPoint
     md = sha256('OutptValueCache')
     md.update(prevout.serialize())
     return b2a_base64(md.digest()[:15])[:-1].decode()
Beispiel #5
0
 def __init__(self):
     self.part = Partition(Partition.RUNNING).get_next_update()
     self.sha = hashlib.sha256()
     self.seq = 0
     self.block = 0
     self.buf = bytearray(BLOCKLEN)
     self.buflen = 0
Beispiel #6
0
    def load_nonce(self, mhash=None):
        "Set TempKey to a known, but randomly-based value"

        if mhash != None:
            # load with known value; won't work with some commands (ReqRandom=1)
            assert len(mhash) == 32

            rv = self.ae_cmd1(opcode=OP.Nonce, p1=3, p2=0, body=mhash)
            if rv:
                raise ChipErrorResponse(hex(rv))

        else:
            # A random number must be involved, so no choice in args to OP.Nonce here (ReqRandom).
            ch2 = random_bytes(20)
            rndout = self.ae_cmd(opcode=OP.Nonce,
                                 p1=0,
                                 p2=0,
                                 resp_len=32,
                                 body=ch2)

            # NOTE: response is the (old) contents of the RNG, not the TempKey value itself.
            assert len(rndout) == 32

            # TempKey on the chip will be set to the output of SHA256 over
            # a message composed of my challenge, the RNG and 3 bytes of constants:
            return sha256(bytes(rndout) + ch2 + b'\x16\0\0').digest()
Beispiel #7
0
    def do_checkmac(self, slot_num, hkey):
        "verify we know the SHA256 key in slot n"
        assert len(hkey) == 32

        # Note: cannot read back while data zone is unlocked, but we
        # can use the key right away in a CheckMac operation and that verifies
        # it real good.

        challenge = self.load_nonce()

        # 32 bytes of "client challenge" and 13 bytes of "other data" are needed, but
        # we have control over their contents.
        ch3 = b'0' * 32  # unused/padding
        od = random_bytes(13)
        msg = hkey + challenge + od[0:4] + (b'\0'*8) + od[4:7] + b'\xee' \
                    + od[7:11] + b'\x01\x23' + od[11:13]
        assert len(msg) == 32 + 32 + 4 + 8 + 3 + 1 + 4 + 2 + 2
        resp = sha256(msg).digest()
        body = ch3 + resp + od
        assert len(body) == 32 + 32 + 13
        # mode=p1 must be 0x01 ... for AuthKey effect to be applied
        rv = self.ae_cmd1(opcode=OP.CheckMac, p1=0x1, p2=slot_num, body=body)

        if rv == 1:
            raise WrongMacVerify()
        elif rv:
            raise ChipErrorResponse(hex(rv))

        info = self.get_info()
        #print("After CheckMac Info = %r" % info)
        #assert info.TK_Valid == 0, info           # zero=consumed, but sometimes 1 if used for copy
        assert info.AuthKey == slot_num, info
        assert info.AuthValid == 1, 'AuthValid clear: %r' % info

        self.reset_watchdog()
Beispiel #8
0
    def write_encrypted(self, slot_num, write_kn, write_key, new_value):
        # use our knowledge of slot write_kn, to unlock and do encrypted-write into slot_num
        assert len(new_value) == 32
        assert len(write_key) == 32

        assert self.is_data_locked(
        ), "enc write w/ data unlocked writes garbage"

        dig = self.gendig_slot(write_kn, write_key)
        #print("After gendig:\n%r" % self.get_info())
        self.reset_watchdog()

        enc = bytes(a ^ b for a, b in zip(dig, new_value))

        args = write_params(slot=slot_num,
                            block=0,
                            offset=0,
                            is_data=True,
                            sz=0x80)
        #print("WRITE: %r data=%s" % (args, b2a_hex(data[0:32])))
        assert len(enc) == 32

        # "authorizing mac" is also required to be sent:
        # SHA-256(TempKey, Opcode, Param1, Param2, SN<8>, SN<0:1>, <25 bytes of zeros>, PlainTextData)
        msg = (dig + ustruct.pack('<bbH', OP.Write, args['p1'], args['p2']) +
               b'\xee\x01\x23' + (b'\0' * 25) + new_value)
        assert len(msg) == 32 + 1 + 1 + 2 + 1 + 2 + 25 + 32

        auth_mac = sha256(msg).digest()

        rv = self.ae_cmd1(body=enc + auth_mac, **args)
        if rv:
            raise ChipErrorResponse(hex(rv))
Beispiel #9
0
    def sendTemp(self):
        print("Sending temperature...", end="")
        temp = self.get_temp()
        random = urandom.getrandbits(32)
        hash = uhashlib.sha256()
        hash.update(
            str(esptempconfig.api_id) + str(random) + str(temp) +
            esptempconfig.api_key)
        signature = ubinascii.hexlify(hash.digest()).decode()
        data = "sensor={}&time={}&temp={}&signature={}".format(
            esptempconfig.api_id, random, temp, signature)

        resp = urequests.post(
            esptempconfig.api_endpoint,
            headers={'content-type': 'application/x-www-form-urlencoded'},
            data=data)

        if resp.status_code == 200:
            print("OK")
            return True
        else:
            print("FAILED")
            print("  Data: {}".format(data))
            print("  HTTP-Status: {}".format(resp.status_code))
            print("  Response: {}".format(resp.text))
            return False
Beispiel #10
0
    def get_device_id(self):
        """Get an identifier for the device used in server requests
        In this case, we return the SHA256 hash of the SIM ICCID prefixed with
        'ID:' and then prepend an 'IC' (for ICCID) so the result is e.g.
        devid = 'IC' + SHA256("ID:12345678901234567890")
              = IC27c6bb74efe9633181ae95bade7740969df13ef15bca1d72a92aa19fb66d24c9"""

        try:
            connection = self.lte.isconnected(
            )  #save connection state on entry
            if connection:  #we are connected at this point and must pause the data session
                self.lte.pppsuspend()
            iccid = self.lte.iccid()
            if connection:  #if there was a connection, resume it
                self.lte.pppresume()
        except Exception as e:
            print("Getting device ID failed:")
            print(e)
            return "ICERROR"

        hasher = None
        try:
            hasher = uhashlib.sha256("ID:" + iccid)
            hashvalue = hasher.digest()
        except Exception as e:
            if hasher is not None:
                hasher.digest(
                )  #make sure hasher is closed, as only one is allowed at a time by the hardware
            raise e

        devid = "IC" + ubinascii.hexlify(hashvalue).decode('utf-8')

        return devid
Beispiel #11
0
def getNextAssertion():
    global ks_ctap2
    global NEXT_CREDENTIAL_TIMER, REM_GETASSERTION_PARAMETERS
    global CREDENTIALCOUNTER, NUMBEROFCREDENTIALS
    global REM_GETASSERTION_PARAMETERS_COMMON, REM_LAST_CMD
    if not REM_GETASSERTION_PARAMETERS:
        return CTAP2_ERR_NOT_ALLOWED
    if REM_LAST_CMD not in(authenticatorGetAssertion, authenticatorGetNextAssertion):
        return CTAP2_ERR_NOT_ALLOWED
    if CREDENTIALCOUNTER >= NUMBEROFCREDENTIALS:
        return CTAP2_ERR_NOT_ALLOWED
    if ticks_diff(ticks_ms(), NEXT_CREDENTIAL_TIMER) > 30000:
        return CTAP2_ERR_NOT_ALLOWED
    d, user_description, credentialID = REM_GETASSERTION_PARAMETERS.pop()
    rp_id_hash, clientDataHash, FLAGS, useRK = REM_GETASSERTION_PARAMETERS_COMMON
    # increase signature counter
    ks_ctap2.COUNTER = (ks_ctap2.COUNTER + 1) % 0x0100000000
    cb = ks_ctap2.COUNTER.to_bytes(4, 'big')
    # authenticator data: https://www.w3.org/TR/webauthn/#table-authData
    auth_data = rp_id_hash + FLAGS + cb
    # compute signature
    s = sha256(auth_data + clientDataHash)  # auth_data + client_data_hash
    h = int.from_bytes(s.digest(), 'big', False)
    signature = ecdsa_sign(secp256r1, d, h)
    CREDENTIALCOUNTER += 1
    NEXT_CREDENTIAL_TIMER = ticks_ms()
    ret = {1: {'id': credentialID, 'type': 'public-key'},
           2: auth_data,
           3: signature}
    if useRK is True:
        ret[4] = user_description
    return CTAP2_OK + encode(ret)
Beispiel #12
0
    def check_manifest_signature(self, manifest: str, sig_type: str,
                                 sig_data: str) -> bool:

        if (sig_type == "SIG01_PKCS1_PSS_4096_SHA256"):
            verifier = PKCS1_PSSVerifier(hasher=uhashlib.sha256)
            pub_modulus = self.PUB_MOD_RSA_4096
            hasher = uhashlib.sha256(manifest)
            manifest_hash = hasher.digest()
            return verifier.verify(manifest_hash,
                                   sig_data,
                                   pub_modulus,
                                   modBits=4096)
        elif (sig_type == "SIG02_PKCS1_PSS_4096_SHA512"):
            verifier = PKCS1_PSSVerifier(hasher=uhashlib.sha512)
            pub_modulus = self.PUB_MOD_RSA_4096
            hasher = uhashlib.sha512(manifest)
            manifest_hash = hasher.digest()
            return verifier.verify(manifest_hash,
                                   sig_data,
                                   pub_modulus,
                                   modBits=4096)
        else:
            raise Exception("Unknown signature type: {}".format(sig_type))

        raise Exception(
            "Something is wrong with check_manifest_signature(), you should not have reached this line."
        )
Beispiel #13
0
    async def handle_download(self, offset, length, file_number):
        # let them read from where we store the signed txn
        # - filenumber can be 0 or 1: uploaded txn, or result
        from sflash import SF

        # limiting memory use here, should be MAX_BLK_LEN really
        length = min(length, MAX_BLK_LEN)

        assert 0 <= file_number < 2, 'bad fnum'
        assert 0 <= offset <= MAX_TXN_LEN, "bad offset"
        assert 1 <= length, 'len'

        # maintain a running SHA256 over what's sent
        if offset == 0:
            self.file_checksum = sha256()

        pos = (MAX_TXN_LEN * file_number) + offset

        resp = bytearray(4 + length)
        resp[0:4] = b'biny'
        SF.read(pos, memoryview(resp)[4:])

        self.file_checksum.update(memoryview(resp)[4:])

        return resp
Beispiel #14
0
 def _auth_server_respond(self, topic, msg):
     if b'client-auth' in topic:
         msg_hash = sha256(msg)
         if (hexlify(msg_hash.digest()) == MODULE_SERIAL_HASH):
             self._server_trust = True
             return
     raise OSError(-1)
Beispiel #15
0
def u2f_authenticate(control_byte, req):
    # https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-raw-message-formats-v1.2-ps-20170411.html#authentication-messages
    global ks_u2f
    L = req[64]
    if L != KEY_HANDLE_LENGTH:
        return SW_WRONG_DATA
    if len(req) != 64 + 1 + L:
        return SW_CONDITIONS_NOT_SATISFIED
    if control_byte not in (0x03, 0x07, 0x08):
        return SW_CONDITIONS_NOT_SATISFIED
    key_handle = dec_key_handle(req[65:], req[32:64])
    if key_handle == b'':
        return SW_WRONG_DATA
    if control_byte == 0x07:  # check-only
        return SW_CONDITIONS_NOT_SATISFIED
    user_presemce = b'\x00'
    if control_byte == 0x03:  # enforce-user-presence-and-sign
        if (up_check() is False):
            return SW_CONDITIONS_NOT_SATISFIED
        user_presemce = b'\x01'
    private_key = int.from_bytes(key_handle[:32], 'big', False)
    ks_u2f.COUNTER = (ks_u2f.COUNTER + 1) % 0x0100000000
    cb = ks_u2f.COUNTER.to_bytes(4, 'big')
    s = sha256(req[32:64] + user_presemce + cb + req[:32])
    h = int.from_bytes(s.digest(), 'big', False)
    signature = ecdsa_sign(secp256r1, private_key, h)
    return user_presemce + cb + signature + SW_NO_ERROR
Beispiel #16
0
    def get_device_id(self):
        #TODO For Wifi, change this to something like the mac address instead of SIM ICCID
        """Get an identifier for the device used in server requests
        In this case, we return the SHA256 hash of the SIM ICCID prefixed with
        'ID:' and then prepend an 'IC' (for ICCID) so the result is e.g.
        devid = 'IC' + SHA256("ID:12345678901234567890")
              = IC27c6bb74efe9633181ae95bade7740969df13ef15bca1d72a92aa19fb66d24c9"""

        try:
            lte = LTE()
            iccid = lte.iccid()
        except Exception as e:
            print("Getting device ID failed:")
            print(e)
            return "ICERROR"

        hasher = None
        try:
            hasher = uhashlib.sha256("ID:" + iccid)
            hashvalue = hasher.digest()
        except Exception as e:
            if hasher is not None:
                hasher.digest(
                )  #make sure hasher is closed, as only one is allowed at a time by the hardware
            raise e

        devid = "IC" + ubinascii.hexlify(hashvalue).decode('utf-8')

        return devid
Beispiel #17
0
def pin_prefix(pin, buf_out):
    # return 4 bytes (32-bit number)
    # real thing is nothing like this!
    from uhashlib import sha256

    buf_out[0:4] = sha256(pin).digest()[0:4]

    return 0
Beispiel #18
0
async def add_dice_rolls(count, seed, judge_them):
    from glob import dis
    from display import FontTiny, FontLarge

    md = sha256(seed)
    pr = PressRelease()

    # fixed parts of screen
    dis.clear()
    y = 38
    dis.text(0, y, "Press 1-6 for each dice")
    y += 13
    dis.text(0, y, "roll to mix in.")
    dis.save()

    while 1:
        # Note: cannot scroll this msg because 5=up arrow
        dis.restore()
        dis.text(None, 0, '%d rolls' % count, FontLarge)

        hx = str(b2a_hex(md.digest()), 'ascii')
        dis.text(0, 20, hx[0:32], FontTiny)
        dis.text(0, 20 + 7, hx[32:], FontTiny)

        dis.show()

        ch = await pr.wait()

        if ch in '123456':
            count += 1

            dis.restore()
            dis.text(None, 0, '%d rolls' % count, FontLarge)
            dis.show()

            # this is slow enough to see
            md.update(ch)

        elif ch == 'x':
            # Because the change (roll) has already been applied,
            # only let them abort if it's early still
            if count < 10 and judge_them:
                return 0, seed
        elif ch == 'y':
            if count < 99 and judge_them:
                if not count:
                    return 0, seed
                ok = await ux_confirm('''\
You only provided %d dice rolls, and each roll adds only 2.585 bits of entropy. \
For 128-bit security, which is considered the minimum, you need 50 rolls, and \
for 256-bits of security, 99 rolls.''' % count)
                if not ok: continue
            break

    if count:
        seed = md.digest()

    return count, seed
 def sha256(filename):
   JUNK = 256
   sha = uhashlib.sha256()
   with open(filename, 'rb') as f:
     while True:
       data = f.read(JUNK)
       if len(data) == 0:
         return ubinascii.hexlify(sha.digest())
       sha.update(data)
Beispiel #20
0
def make_checksum(fileobj):
    block = bytearray(512)
    checksum = sha256()
    while True:
        block = fileobj.read(512)
        checksum.update(block)
        if len(block) < 512:
            break
    return (hexlify(checksum.digest()).decode())
Beispiel #21
0
def generate(entropy):
    entbytes = int2bytes(entropy)
    width_bytes = len(entbytes)
    width_bits = width_bytes * 8
    assert width_bits in range(128, 257, 32)
    sha = uhashlib.sha256(int2bytes(entropy)).digest()
    checksum = sha[0:1]
    final = bytes2int(entbytes + checksum)
    mnemonic = [((final & (2047 << (x * 11))) >> (x * 11)) for x in range(24)]
    return list(reversed(mnemonic))
def computeFileHash(theFile):
    f=open(theFile)
    theHash = uhashlib.sha256()
    line = f.readline()
    while line:
        theHash.update(line)
        line = f.readline()
    theRawHash = theHash.digest() # type is 'bytes'
    hexHash =  ubinascii.hexlify(theRawHash) # still 'bytes', but now in hex
    return hexHash.decode()  # hexHash coverted to a string type   
Beispiel #23
0
def dump_wirebytes(data):
    (options, body) = dump_header(data)
    if len(options) > 0:
        print('hdr.option=%d bytes' % len(options))
    print("hdr.end")

    h = sha256()
    h.update(body)
    dump_tlv(body, CTX_TOPLEVEL, 1)
    print("pkt.digest= 0x" + str(pycn_lite.lib.hexlify(h.digest()), 'ascii'))
Beispiel #24
0
    def signing_header(self):
        # payload_hash
        payload_hash = ubinascii.hexlify(
            uhashlib.sha256(self.payload).digest()).decode("utf-8")
        # separate
        if self.signed_headers and len(self.signed_headers) > 0:
            separate = b';'
        else:
            separate = 0
        # canonical_request_sha256
        canonical_request = b"%s\n%s\n%s\n%shost:%s\nx-amz-date:%s\n\n%s%shost;x-amz-date\n%s" % \
            (self.method, self.path, self.query, self.canonical_headers, self.host, self.amz_date, self.signed_headers, separate, payload_hash)
        canonical_request_sha256 = ubinascii.hexlify(
            uhashlib.sha256(canonical_request).digest()).decode("utf-8")
        # credential_scope
        credential_scope = b"%s/%s/%s/aws4_request" % (
            self.date_stamp, self.region, self.service_name)
        # signing_key
        aws4_key = b"AWS4%s" % (self.secret)
        k_date = hmac.new(aws4_key, self.date_stamp,
                          digestmod=uhashlib.sha256).digest()
        k_region = hmac.new(k_date, self.region,
                            digestmod=uhashlib.sha256).digest()
        k_service = hmac.new(k_region,
                             self.service_name,
                             digestmod=uhashlib.sha256).digest()
        signing_key = hmac.new(k_service,
                               b'aws4_request',
                               digestmod=uhashlib.sha256).digest()

        string_to_sign = b"%s\n%s\n%s\n%s" % (b"AWS4-HMAC-SHA256",
                                              self.amz_date, credential_scope,
                                              canonical_request_sha256)

        signature = ubinascii.hexlify(
            hmac.new(signing_key, string_to_sign,
                     digestmod=uhashlib.sha256).digest()).decode("utf-8")

        authorization_header = b"%s Credential=%s/%s, SignedHeaders=%s%shost;x-amz-date, Signature=%s" % \
            (b"AWS4-HMAC-SHA256", self.key, credential_scope, self.signed_headers, separate, signature)

        return authorization_header
Beispiel #25
0
    def _authenticate(self, passwd):

        hashwd = uhashlib.sha256(passwd.encode("utf-8")).digest()
        with open("/etc/passwd", "rb") as fs:
            checkwd = fs.read()
            print("orig: %s vs input: %s" % (checkwd, hashwd))
            if checkwd == hashwd:
                self.authenticated = True
                return True
            else:
                return False
Beispiel #26
0
def encode_data_wirebytes(comps, blob):
    buf = bytearray(ccnx.MAX_CHUNK_SIZE)
    start = len(buf)
    start = prepend_blob(buf, start, blob)
    start = prepend_tl(buf, start, ccnx.CCNX_TLV_M_Payload, len(blob))
    start = prepend_name(buf, start, comps)
    start = prepend_tl(buf, start, ccnx.CCNX_TLV_TL_Object, len(buf) - start)
    h = sha256()
    h.update(buf[start:])
    hdr = bytearray(b'\x01\x01  \x10\x00\x00\x08')
    struct.pack_into('>H', hdr, 2, len(buf) - start + len(hdr))
    return (hdr + buf[start:], h.digest())
Beispiel #27
0
def new_message(path: str, device_id: bytes, value: bytes, action: int, dest=DEST_LOCAL):
    tim = time.time()
    key = Key(tim=tim, device_id=device_id)
    
    sha = hashlib.sha256()
    sha.update(path)
    sha.update(str(tim))
    sha.update(device_id)
    sha.update(str(value))
    key.data_id = str(hexlify(sha.digest())[:8], 'utf-8')

    return Message(path, key.string(), value, action, dest)
Beispiel #28
0
def file_hash(fname):
    try:
        hasher = uhashlib.sha256()
        with open(fname, mode="rb") as f:
            chunk = f.read(512)
            while chunk:
                hasher.update(chunk)
                chunk = f.read(512)
        return hasher.digest()
    except Exception as e:
        print("file_hash", e)
    return None
Beispiel #29
0
    def encryption_key(self, salt):
        # Return a 32-byte derived secret to be used for our own internal encryption purposes
        # 0x80000000 - 0xCC30 = 2147431376
        node = self.derive_path("m/2147431408'/0'")     # plan: 0' will be an index for other apps

        acc = sha256(salt)
        acc.update(node.privkey())
        acc.update(salt)

        pk = ngu.hash.sha256s(acc.digest())

        self.register(pk)
        return pk
Beispiel #30
0
def default_remote_id():
    """generate remote id based on machine.unique_id()"""
    import uhashlib
    from ustruct import unpack
    # we compute a hash of board's unique_id, since a boards manufactured
    # closely together probably share prefix or suffix, and I don't know
    # which one. we want to avoid accidental remote_id clashes
    unique_hash = uhashlib.sha256(machine.unique_id()).digest()
    # and a 4 byte prefix of a sha256 hash is more than enough
    uint32 = unpack("I", unique_hash[:4])[0]
    # let's mask it to 26 bits
    uint26 = uint32 & (2**26 - 1)
    return uint26
Beispiel #31
0
def default_remote_id():
    """generate remote id based on machine.unique_id()"""
    import uhashlib
    from ustruct import unpack
    # we compute a hash of board's unique_id, since a boards manufactured
    # closely together probably share prefix or suffix, and I don't know
    # which one. we want to avoid accidental remote_id clashes
    unique_hash = uhashlib.sha256(machine.unique_id()).digest()
    # and a 4 byte prefix of a sha256 hash is more than enough
    uint32 = unpack("I", unique_hash[:4])[0]
    # let's mask it to 26 bits
    uint26 = uint32 & (2**26 - 1)
    return uint26
Beispiel #32
0
try:
    import uhashlib as hashlib
except ImportError:
    try:
        import hashlib
    except ImportError:
        # This is neither uPy, nor cPy, so must be uPy with
        # uhashlib module disabled.
        print("SKIP")
        raise SystemExit


h = hashlib.sha256()
print(h.digest())

h = hashlib.sha256()
h.update(b"123")
print(h.digest())

h = hashlib.sha256()
h.update(b"abcd" * 1000)
print(h.digest())

print(hashlib.sha256(b"\xff" * 64).digest())

# 56 bytes is a boundary case in the algorithm
print(hashlib.sha256(b"\xff" * 56).digest())

# TODO: running .digest() several times in row is not supported()
#h = hashlib.sha256(b'123')
#print(h.digest())