bool IntegerExtractor::Decode(int inputLen, BigInteger &theInt) { if(!mIsValid) return false; if(input.length()<=offset) return false; bool negative = ((PeekByte() & 0x80)!=0) ? true : false; while (inputLen>0 && PeekByte()==0) { offset++; inputLen--; } RawBuffer reg(inputLen,(unsigned char)0); for (int i=0; i<inputLen; i++) { reg[i] = GetByte(); } /* if (negative) { for (int i=inputLen; i<reg.length; i++) reg[i] = (byte)0xff; TwosComplement(reg, reg.length); }*/ theInt.fromBinary(reg); return mIsValid; }
ByteBufferPtr ElGamal::Decrypt(const void *theCipherText, int theCipherTextLen) const { if(!IsPrivate()) return NULL; const unsigned char *in = (const unsigned char*)theCipherText; int inOffset = 0; if(theCipherTextLen-inOffset<4) return NULL; int aNumBlocks = LongFromLittleEndian(*(int*)in); inOffset+=4; if(theCipherTextLen-inOffset < aNumBlocks*modulusLen*2-inOffset) return NULL; RawBuffer aBuf(modulusLen,(unsigned char)0); RawBuffer bBuf(modulusLen,(unsigned char)0); WriteBuffer aDecrypt; BigInteger a;; BigInteger b; BigInteger aPlainText; for(int i=0; i<aNumBlocks; i++) { aBuf.assign(in+inOffset,modulusLen); inOffset+=modulusLen; bBuf.assign(in+inOffset,modulusLen); inOffset+=modulusLen; a.fromBinary(aBuf); b.fromBinary(bBuf); if(!decrypt(a,b,aPlainText)) return NULL; RawBuffer aBigIntArray; aPlainText.toBinary(aBigIntArray); if(aBigIntArray.length()==0) return NULL; int aPlainLen = aBigIntArray[aBigIntArray.length() - 1]; if(aPlainLen>modulusLen - 3) return NULL; if(aBigIntArray.length() - 1 - aPlainLen < 0) { int extra = aPlainLen - (aBigIntArray.length() - 1); for(int j=0; j<extra; j++) aDecrypt.AppendByte(0); aDecrypt.AppendBytes(aBigIntArray.data(),aBigIntArray.length()); } else aDecrypt.AppendBytes(aBigIntArray.data()+aBigIntArray.length()-1-aPlainLen,aPlainLen); } return aDecrypt.ToByteBuffer(); }