You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							88 lines
						
					
					
						
							2.3 KiB
						
					
					
				
			
		
		
	
	
							88 lines
						
					
					
						
							2.3 KiB
						
					
					
				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 | 
						|
}
 | 
						|
 |