def __init__(self, n, e=None): """Pass either two arguments (e,n) to build from existing data, or pass one argument (n=existing key) to build from an existing key.""" if e: eStrLen = 0 tmp = 1L while tmp < e or eStrLen % 2 != 0: tmp *= 256L eStrLen += 1 nStrLen = 0 #NOTE: this is completely bizarre. Why does m2crypto think that we need an odd number of bytes to encode a key? nStrLen += 1 tmp = 1L while tmp < n or eStrLen % 2 != 0: tmp *= 256L nStrLen += 1 eStr = struct.pack(">I%ss" % (eStrLen), eStrLen, Basic.long_to_bytes(e, eStrLen)) nStr = struct.pack(">I%ss" % (nStrLen), nStrLen, Basic.long_to_bytes(n, nStrLen)) self.key = M2Crypto.RSA.new_pub_key((eStr, nStr)) self.e = long(e) self.n = long(n) else: #validate that this is of the correct type: try: if n.__class__.__name__ not in ("RSA", "RSA_pub"): raise Exception("Wrong type") except: raise Exception("n is not the right type: " + str(n)) self.key = n #: length of the key in bytes (used in blinding/unblinding) self.keyLen = len(self.key)
def connectionMade(self): log_msg('Sending login message...', 2) signedFingerprint = Globals.PRIVATE_KEY.sign(Globals.FINGERPRINT) publicKey = Basic.long_to_bytes(long(Globals.PRIVATE_KEY.n), 128) protocol = 1 msg = struct.pack('!B128s50s50s128s', protocol, signedFingerprint, self.factory.username, self.factory.password, publicKey) self.sendString(msg)
def blind(self, message, r, length=None): """Blind a message using random number r (assuming length of the key by default) @param message: string to be blinded @type message: string @param r: blinding factor @type r: long @param length: length of the message after blinding (needed to convert from a long to a string). @type long: None or int @return: string of message blinded with r assuming length of n """ Basic.validate_type(message, types.StringType) Basic.validate_type(r, types.LongType) message = Basic.bytes_to_long(message) tmp = pow(r, self.e, self.n) tmp = (message * tmp) % self.n return Basic.long_to_bytes(tmp, length or self.keyLen)
def make_acoin_request(bank, interval, value): """Create an acoin signing request: @param interval: during which the ACoin will be valid @type interval: int @param value: how much the coin should be worth @type value: int @returns: ACoinRequest""" #determine which bank key to use: bankKey = bank.get_acoin_key(value) numRandomBits = Globals.ACOIN_BYTES * 8 #generate random number for blinding blindingFactor = bankKey.get_blinding_factor(numRandomBits) #generate random number receipt to be signed receipt = Basic.long_to_bytes(random.getrandbits(numRandomBits), Globals.ACOIN_BYTES) #the base message is the receipt and interval msg = ACoin.ACoin.pack_acoin_for_signing(receipt, interval) #blind the message: msg = bankKey.blind(msg, blindingFactor, Globals.ACOIN_KEY_BYTES) return ACoinRequest(blindingFactor, receipt, msg, interval, value)