var forge=require("./forge");require("./random"),require("./util");var pss=module.exports=forge.pss=forge.pss||{};pss.create=function(e){3==arguments.length&&(e={md:arguments[0],mgf:arguments[1],saltLength:arguments[2]});var t,r=e.md,o=e.mgf,s=r.digestLength,n=e.salt||null;if("string"==typeof n&&(n=forge.util.createBuffer(n)),"saltLength"in e)t=e.saltLength;else if(null!==n)t=n.length();else throw Error("Salt length not specified or specific salt not given.");if(null!==n&&n.length()!==t)throw Error("Given salt length does not match length of given salt.");var a=e.prng||forge.random,i={};return i.encode=function(e,i){var f,g,u=i-1,h=Math.ceil(u/8),l=e.digest().getBytes();if(h<s+t+2)throw Error("Message is too long to encrypt.");g=null===n?a.getBytesSync(t):n.bytes();var d=new forge.util.ByteBuffer;d.fillWithByte(0,8),d.putBytes(l),d.putBytes(g),r.start(),r.update(d.getBytes());var c=r.digest().getBytes(),y=new forge.util.ByteBuffer;y.fillWithByte(0,h-t-s-2),y.putByte(1),y.putBytes(g);var B=y.getBytes(),p=h-s-1,C=o.generate(c,p),v="";for(f=0;f<p;f++)v+=String.fromCharCode(B.charCodeAt(f)^C.charCodeAt(f));return(v=String.fromCharCode(v.charCodeAt(0)&~(65280>>8*h-u&255))+v.substr(1))+c+String.fromCharCode(188)},i.verify=function(e,n,a){var i,f=a-1,g=Math.ceil(f/8);if(n=n.substr(-g),g<s+t+2)throw Error("Inconsistent parameters to PSS signature verification.");if(188!==n.charCodeAt(g-1))throw Error("Encoded message does not end in 0xBC.");var u=g-s-1,h=n.substr(0,u),l=n.substr(u,s),d=65280>>8*g-f&255;if((h.charCodeAt(0)&d)!=0)throw Error("Bits beyond keysize not zero as expected.");var c=o.generate(l,u),y="";for(i=0;i<u;i++)y+=String.fromCharCode(h.charCodeAt(i)^c.charCodeAt(i));y=String.fromCharCode(y.charCodeAt(0)&~d)+y.substr(1);var B=g-s-t-2;for(i=0;i<B;i++)if(0!==y.charCodeAt(i))throw Error("Leftmost octets not zero as expected");if(1!==y.charCodeAt(B))throw Error("Inconsistent PSS signature, 0x01 marker not found");var p=y.substr(-t),C=new forge.util.ByteBuffer;return C.fillWithByte(0,8),C.putBytes(e),C.putBytes(p),r.start(),r.update(C.getBytes()),l===r.digest().getBytes()},i};