3

I would like to know how I can convert an integer into a binary number in a sequence of length = 32 bytes and least-significant-bit first encoding, in Python 3.

I need to do this conversion for an exercise in my cryptography class. I have tried the python function int.to_bytes() but it seems not working...

The integer I would like to convert is x = 999.

This is my code if it can help:

def reading_a_pdf_file (filename):

    rfile = open(filename, 'rb')
    contains = rfile.read();
    rfile.close();
    return contains
# ...

def writing_in_a_pdf_file (filename, txt):

    wfile = open(filename, 'wb')
    wfile.write(txt)
    wfile.close()
# ...

import nacl.secret
import nacl.utils 


x= 999
key = x.to_bytes(32, byteorder='little')

# creating the box of encryption/decryption
box = nacl.secret.SecretBox(key)


# reading the encrypted file
encrypted = reading_a_pdf_file('L12-14.enc.pdf')

# we decrypt the contain of the file
decrypted = box.decrypt(encrypted)

# finally we save into a new pdf file
writing_in_a_pdf_file('L12-14.pdf', decrypted)


print("The file have been successfully decrypted in 'L12-14.pdf'")

At the end of the program, I am supposed to get the file L12-14.pdf, but I get the error: "Decryption failed. Ciphertext failed verification" which means that my key is not the good one.

As I know the integer is right, I suppose I am making a mistake when I convert it.

Can you help me ?

glibdud
  • 7,550
  • 4
  • 27
  • 37
gommy
  • 41
  • 5
  • 1
    there is another question that appears similar to what you are asking https://stackoverflow.com/questions/699866/python-int-to-binary – Rob Dec 19 '18 at 12:59
  • Actually this does not work well for negative numbers and I did not find a quick way to enforce a 32 bit representation. – Rob Dec 19 '18 at 13:05
  • Can you be more specific about how it's not working? Please edit the question to show example inputs, the code you're using to try to convert them, and the expected vs. actual outputs. – glibdud Dec 19 '18 at 13:08
  • The number I would like to convert is x = 999. I want to convert it to use the NaCl encryption that I used for my cryptography class, but when I convert with the int.to_bytes() function the decryption failed which means that the key (so my conversion) is false – gommy Dec 19 '18 at 13:13
  • Please edit that into the question, along with what code you used to try to convert it, the result you got, and the result you're looking for. – glibdud Dec 19 '18 at 13:16
  • @gommy Based on your description, you're doing exactly what you should be doing. Either you misinterpreted how you're supposed to create the key, or the file itself may be corrupted. If it's something you downloaded, try redownloading it. Check the file size and, if available, the file's hash to make sure it's good. – glibdud Dec 19 '18 at 13:33
  • @glibdud, I can give you the entire question from my exercise: decrypt this file encrypted via NaCL encryption using the smallest positive solution to 1000^x = 13618050 (mod 15484879) as key, where x is written as binary number in a sequence of length = 32 bytes and least-significant-bit first encoding. So I have solved the equation and I got x = 999. – gommy Dec 19 '18 at 13:41
  • I miss understood what you wanted :( – Rob Dec 19 '18 at 13:41
  • Usually when we talk about the order in which binary data is presented, we talk in terms of bytes (least significant byte first, for example). If your assignment literally wants least significant *bit* first, then that's probably the source of the problem. I don't know of a built-in way to do that in python. You may have to play with strings after all. – glibdud Dec 19 '18 at 13:59
  • This isn't a complete solution, but it might help you along: [Reversing bits of Python integer](https://stackoverflow.com/questions/12681945/reversing-bits-of-python-integer) – glibdud Dec 19 '18 at 14:00
  • thank you for all @glibdud I will look at it. – gommy Dec 20 '18 at 09:12

1 Answers1

1

so first of all: Welcome to Mr. Lutenberger's course, we're sharing a lecture here.

The issue is in fact the LSB-encoding of the binary number. I won't outline the complete solution, in hope that you can solve this on your own. If it doesn't work ping me, i got it decrypted and can give you further hints.

So, you have 999 as a solution. Converted to binary, that is 1111100111. Note however, that this is in MSB and has 10 bits (both is important later).

First thing to do: swap the number into LSB. This is essentially swapping the bits. NOTE: at this point, do NOT preprend or append 0's to fill up bytes!

Now that you have the number in LSB, you want to have it in reverse byte order in Python, as passing this directly would result in a bunch of 0's and the data at the end. You correctly used byteorder=little here. However, the number that we have here is 10 bit large, so it spans across TWO bytes. So for us to have the bytes AND bits in the correct order AND both in the beginning of our 32 byte stream we have to switch the two bytes involved as well, as the second byte (the "end" of the number) will be the first one after applying byteorder=little. For this step, the second byte has to be appended 6 0's to fill it up before swapping, in ordr to keep the bytes "seperate".

Now with your manipulated head of the byte stream, decode the value as int and pass that as value to your x. That should work. Hint: x has 5 digits now.

As a side note: may i ask how you calculated 999?

flex
  • 26
  • 1
  • In this case, I just try by iteration all solutions from 1 to 999. To do that I use the principle of congruences which say : 1000^x = 1000^(x-1) * 1000 [n]. – gommy Jan 22 '19 at 17:29