text: var parseKeys = require('parse-asn1')
  var randomBytes = require('randombytes')
  var createHash = require('create-hash')
  var mgf = require('./mgf')
  var xor = require('./xor')
  var BN = require('bn.js')
  var withPublic = require('./withPublic')
  var crt = require('browserify-rsa')
  var Buffer = require('safe-buffer').Buffer
  
  module.exports = function publicEncrypt (publicKey, msg, reverse) {
    var padding
    if (publicKey.padding) {
      padding = publicKey.padding
    } else if (reverse) {
      padding = 1
    } else {
      padding = 4
    }
    var key = parseKeys(publicKey)
    var paddedMsg
    if (padding === 4) {
      paddedMsg = oaep(key, msg)
    } else if (padding === 1) {
      paddedMsg = pkcs1(key, msg, reverse)
    } else if (padding === 3) {
      paddedMsg = new BN(msg)
      if (paddedMsg.cmp(key.modulus) >= 0) {
        throw new Error('data too long for modulus')
      }
    } else {
      throw new Error('unknown padding')
    }
    if (reverse) {
      return crt(paddedMsg, key)
    } else {
      return withPublic(paddedMsg, key)
    }
  }
  
  function oaep (key, msg) {
    var k = key.modulus.byteLength()
    var mLen = msg.length
    var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()
    var hLen = iHash.length
    var hLen2 = 2 * hLen
    if (mLen > k - hLen2 - 2) {
      throw new Error('message too long')
    }
    var ps = Buffer.alloc(k - mLen - hLen2 - 2)
    var dblen = k - hLen - 1
    var seed = randomBytes(hLen)
    var maskedDb = xor(Buffer.concat([iHash, ps, Buffer.alloc(1, 1), msg], dblen), mgf(seed, dblen))
    var maskedSeed = xor(seed, mgf(maskedDb, hLen))
    return new BN(Buffer.concat([Buffer.alloc(1), maskedSeed, maskedDb], k))
  }
  function pkcs1 (key, msg, reverse) {
    var mLen = msg.length
    var k = key.modulus.byteLength()
    if (mLen > k - 11) {
      throw new Error('message too long')
    }
    var ps
    if (reverse) {
      ps = Buffer.alloc(k - mLen - 3, 0xff)
    } else {
      ps = nonZero(k - mLen - 3)
    }
    return new BN(Buffer.concat([Buffer.from([0, reverse ? 1 : 2]), ps, Buffer.alloc(1), msg], k))
  }
  function nonZero (len) {
    var out = Buffer.allocUnsafe(len)
    var i = 0
    var cache = randomBytes(len * 2)
    var cur = 0
    var num
    while (i < len) {
      if (cur === cache.length) {
        cache = randomBytes(len * 2)
        cur = 0
      }
      num = cache[cur++]
      if (num) {
        out[i++] = num
      }
    }
    return out
  }
  