aboutsummaryrefslogblamecommitdiff
path: root/frozen_deps/Cryptodome/Util/RFC1751.py
blob: 10859c3ff6323891c6a5ca502c6487ff8aef5a3b (plain) (tree)

























                                                                     
                                     

               
 





                                                                             


                                                  

                                                           

                      
 


                                                                                              
 



















                                                                         
       






                                                                          
                                       



                                         
                                          
                                                       
                                  
                                                                      
 
                          
 














                                                                    

       

                         
                                     


                                    

                                     
                                             
                              














                                                                  

                                               




                                             
                                                             
                               

              


                                                

















































































































































































































































                                                                        
# rfc1751.py : Converts between 128-bit strings and a human-readable
# sequence of words, as defined in RFC1751: "A Convention for
# Human-Readable 128-bit Keys", by Daniel L. McDonald.
#
# Part of the Python Cryptography Toolkit
#
# Written by Andrew M. Kuchling and others
#
# ===================================================================
# The contents of this file are dedicated to the public domain.  To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# 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.
# ===================================================================

from __future__ import print_function

import binascii

from Cryptodome.Util.py3compat import bord, bchr

binary = {0: '0000', 1: '0001', 2: '0010', 3: '0011', 4: '0100', 5: '0101',
          6: '0110', 7: '0111', 8: '1000', 9: '1001', 10: '1010', 11: '1011',
          12: '1100', 13: '1101', 14: '1110', 15: '1111'}


def _key2bin(s):
    "Convert a key into a string of binary digits"
    kl = map(lambda x: bord(x), s)
    kl = map(lambda x: binary[x >> 4] + binary[x & 15], kl)
    return ''.join(kl)


def _extract(key, start, length):
    """Extract a bitstring(2.x)/bytestring(2.x) from a string of binary digits, and return its
    numeric value."""

    result = 0
    for y in key[start:start+length]:
        result = result * 2 + ord(y) - 48
    return result


def key_to_english(key):
    """Transform an arbitrary key into a string containing English words.

    Example::

        >>> from Cryptodome.Util.RFC1751 import key_to_english
        >>> key_to_english(b'66666666')
        'RAM LOIS GOAD CREW CARE HIT'

    Args:
      key (byte string):
        The key to convert. Its length must be a multiple of 8.
    Return:
      A string of English words.
    """

    if len(key) % 8 != 0:
        raise ValueError('The length of the key must be a multiple of 8.')

    english = ''
    for index in range(0, len(key), 8):  # Loop over 8-byte subkeys
        subkey = key[index:index + 8]
        # Compute the parity of the key
        skbin = _key2bin(subkey)
        p = 0
        for i in range(0, 64, 2):
            p = p + _extract(skbin, i, 2)
        # Append parity bits to the subkey
        skbin = _key2bin(subkey + bchr((p << 6) & 255))
        for i in range(0, 64, 11):
            english = english + wordlist[_extract(skbin, i, 11)] + ' '

    return english.strip()


def english_to_key(s):
    """Transform a string into a corresponding key.

    Example::

        >>> from Cryptodome.Util.RFC1751 import english_to_key
        >>> english_to_key('RAM LOIS GOAD CREW CARE HIT')
        b'66666666'

    Args:
      s (string): the string with the words separated by whitespace;
                  the number of words must be a multiple of 6.
    Return:
      A byte string.
    """

    L = s.upper().split()
    key = b''
    for index in range(0, len(L), 6):
        sublist = L[index:index + 6]
        char = 9 * [0]
        bits = 0
        for i in sublist:
            index = wordlist.index(i)
            shift = (8 - (bits + 11) % 8) % 8
            y = index << shift
            cl, cc, cr = (y >> 16), (y >> 8) & 0xff, y & 0xff
            if (shift > 5):
                char[bits >> 3] = char[bits >> 3] | cl
                char[(bits >> 3) + 1] = char[(bits >> 3) + 1] | cc
                char[(bits >> 3) + 2] = char[(bits >> 3) + 2] | cr
            elif shift > -3:
                char[bits >> 3] = char[bits >> 3] | cc
                char[(bits >> 3) + 1] = char[(bits >> 3) + 1] | cr
            else:
                char[bits >> 3] = char[bits >> 3] | cr
            bits = bits + 11

        subkey = b''
        for y in char:
            subkey = subkey + bchr(y)

        # Check the parity of the resulting key
        skbin = _key2bin(subkey)
        p = 0
        for i in range(0, 64, 2):
            p = p + _extract(skbin, i, 2)
        if (p & 3) != _extract(skbin, 64, 2):
            raise ValueError("Parity error in resulting key")
        key = key + subkey[0:8]
    return key


wordlist = [
   "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
   "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
   "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
   "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
   "AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
   "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
   "BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
   "BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
   "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
   "CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
   "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
   "DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
   "DIN"