I know how to generate them on bitcoin-qt but I am looking for the process of generating them. I want to write my own program that can generate them so I am looking for more of the step by step of hashing functions and what data needs to be put into those hash to create a mutli-sig address. I know you need the public keys uncompressed and the required n value and I know the version bytes are 0x05.
The bitcoin scripts are pretty simple, but making sure you're doing the right thing can be challenging -- for instance, you can create multi-sig script for receiving the money, but most tools don't display and validate the script properly. You'll have to make sure you do that part correctly, too. Luckily, if you do it wrong, the network likely won't propagate it (just don't mine it yourself!).
If you want to use P2SH, you would hash the output script and construct the address string using 0x05 instead of 0x00 as you would for a normal address. But this is irrelevant if you're manually creating transactions, since the network never sees that prefix byte -- it's only an identifier for the address strings that are passed around between humans, but are not included in the actual scripts inserted into the blockchain.
But if you're doing a lot of one-off multi-sig transactions, and not necessarily interacting with others (for now, maybe you just want to protect your own money with this tool you're creating), then I would recommend using vanilla multi-sig without P2SH. This will make it easier to find your money if you later need to search the blockchain for multi-sig addresses that are relevant to your wallets (P2SH will hide those details). A full-featured multi-sig solution (like Armory will hopefully do soon) will use multiple wallets with meta-data and a structured key selection that makes P2SH safe in this respect. Until then, you can use plain multisig scripts which are standard up to 3-of-3.
Finally, I recommend you do all your testing on testnet. Everything is identical, except if you do use P2SH, use the following prefix bytes for generating address strings:
Regular Addresses = '\x6f'
P2SH Addresses = '\xc4'
Onto the fun part -- this can all be done with armoryengine. And the latest version of armoryengine also recognizes and displays P2SH addresses (on the "testing" branch), though it doesn't quite know what to do with multisig scripts. Nonetheless, you can manually put together the pieces using
https://bitcoinarmory.com/developers/python-scripting/ as a guide.
If I was going to do it, I would use regular multisig: I would probably use Armory GUI to create a transaction sending X coins to a regular address, but don't send it yet, create an unsigned transaction. Then go hex-diving into that transaction and replace the TxOut script (and var_int preceeding it) with the multisig script. In fact, you can create the script with my untested function
pubkeylist_to_multisig_script(pubKeyList, Mreq). Though, it's a very simple script:
OP_2 PubKeyA PubKeyB PubKeyC OP_3 OP_CHECKMULTISIG
If you're doing 2-of-3, get the three public keys, and put the
binary forms of them into a list, something like:
pubkeys = ['']*3
pubkeys[0] = hex_to_binary('0438c80fa100871bc8115311d...')
pubkeys[1] = hex_to_binary('047613d073ff18301aab45df1...')
pubkeys[2] = hex_to_binary('040f83e3d9983aba4246fe3aa...')
msScript = pubkeylist_to_multisig_script(pubkeys, 2)
msScript = script_to_p2sh_script(msScript) # OPTIONAL if you want P2SH
scriptSizeVarint = packVarInt(len(script))[0]
Now remove the var_int and script from the recipient txout (don't mess with the change output!), and put this varInt and script in there. Unless I missed something, this should be a valid transaction. You should be able to sign and broadcast it (you might even be able to do it with Armory as if it was an offline transaction, though it also might choke on the form of the receipient "address" -- let me know!).
Spending it, is more challenging with the available tools, but it can be done. The gist of it is that you will create the spending transaction, using as an input the unspent multi-sig (or P2SH) TxOut. You will create the TxIn script using the standard form
OP_0 SigAOrEmptyString SigBOrEmptyString SigCOrEmptyString
You will need the code
here to produce the hash that needs to be signed for OP_CHECKSIG/OP_CHECKMULTSIG. You will sign that hash with each of 2 of the 3 private keys, and put an empty string (OP_0?) in the other location (they need to be in same order as the keys in the TxOut script). That should be a valid spend script.
Of course, I probably missed all sorts of small details, but it's late, so I'll have to defer discussion of those details until later. Hopefully that's at least enough to get you started.