private static mpz_t ImportDataToGmp(byte[] data) { mpz_t result = new(); gmp_lib.mpz_init(result); ulong memorySize = ulong.Parse(data.Length.ToString()); using void_ptr memoryChunk = gmp_lib.allocate(memorySize); Marshal.Copy(data, 0, memoryChunk.ToIntPtr(), data.Length); gmp_lib.mpz_import(result, ulong.Parse(data.Length.ToString()), 1, 1, 1, 0, memoryChunk); return(result); }
public (ReadOnlyMemory <byte>, bool) Run(ReadOnlyMemory <byte> inputData, IReleaseSpec releaseSpec) { Metrics.ModExpPrecompile++; (int baseLength, int expLength, int modulusLength) = GetInputLengths(inputData); byte[] modulusData = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength + expLength, modulusLength); using mpz_t modulusInt = ImportDataToGmp(modulusData); if (gmp_lib.mpz_sgn(modulusInt) == 0) { return(new byte[modulusLength], true); } byte[] baseData = inputData.Span.SliceWithZeroPaddingEmptyOnError(96, baseLength); using mpz_t baseInt = ImportDataToGmp(baseData); byte[] expData = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength, expLength); using mpz_t expInt = ImportDataToGmp(expData); using mpz_t powmResult = new(); gmp_lib.mpz_init(powmResult); gmp_lib.mpz_powm(powmResult, baseInt, expInt, modulusInt); using void_ptr data = gmp_lib.allocate((size_t)modulusLength); ptr <size_t> countp = new(0); gmp_lib.mpz_export(data, countp, 1, 1, 1, 0, powmResult); int count = (int)countp.Value; byte[] result = new byte[modulusLength]; Marshal.Copy(data.ToIntPtr(), result, modulusLength - count, count); return(result, true); }