I wrote some code to calculate an estimate for multisig transaction size based on Karimkorun's almost unreadable answer and based off the (incomplete) documentation here.
The code:
var pubkeySize = 33
var sigSize = 72
// An approximation based on the example in
// https://en.bitcoin.it/wiki/Protocol_documentation#tx
var pubkeyScriptSize = 25
var m = 2, n = 3
var result = tx([input(m,n)], [output(1,1), output(m,n)])
console.log(result)
// All functions calculate sizes
function input(m, n) {
var outpoint = 32 + 4
var sequence = 4
return outpoint + varIntAndValue(sigScript(m, n)) + sequence
}
function sigScript(m, n) {
return 1 + m * (1 + sigSize) + varIntAndValue(redeemScript(n))
}
function redeemScript(n) {
return 1 + n * pubkeySize + 1 + 1
}
function output(m, n) {
var outputValue = 8
return outputValue + pubkeyScript(m, n)
}
function pubkeyScript(m, n) {
return varIntAndValue(pubkeyScriptSize)
}
function tx(inputs, outputs) {
var versionSize = 4
var lockTime = 4
return versionSize + varInt(inputs.length) + sum(inputs)
+ varInt(outputs.length) + sum(outputs) + lockTime
}
// The size of a variable integer for the given value.
// See https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
function varInt(value) {
if (value < 0xFD) {
return 1
} else if (value <= 0xFFFF) {
return 3
} else if (value <= 0xFFFFFFFF) {
return 5
} else {
return 9
}
}
function varIntAndValue(value) {
return varInt(value) + value
}
function sum(list) {
return list.reduce((acc, x) => acc + x, 0)
}