2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
namespace Microsoft.Singularity.Crypto.PublicKey
|
|
|
|
{
|
2008-03-05 09:52:00 -05:00
|
|
|
internal class Digit2 {
|
|
|
|
internal static Digit Lo(UInt64 x) {
|
|
|
|
return unchecked((UInt32)(x & Digit.MaxValue));
|
|
|
|
}
|
|
|
|
internal static Digit Hi(UInt64 x) {
|
|
|
|
Digit hi = unchecked((UInt32)(x >> Digit.BitN));
|
|
|
|
return hi;
|
|
|
|
}
|
|
|
|
internal static void
|
|
|
|
Div(UInt64 num, Digit denom, out Digit q, out Digit r) {
|
|
|
|
Digit numHi = Hi(num), numLo = Lo(num);
|
2008-11-17 18:29:00 -05:00
|
|
|
if (numHi >= denom) {
|
|
|
|
throw new ArgumentException();
|
|
|
|
}
|
2008-03-05 09:52:00 -05:00
|
|
|
q = (Digit)(num / denom);
|
|
|
|
r = unchecked(numLo - denom * q);
|
|
|
|
Digit rr = unchecked((Digit)(num - denom * q));
|
|
|
|
Debug.Assert(rr == r, "internal error");
|
|
|
|
}
|
|
|
|
internal static void Div(
|
|
|
|
UInt64 num
|
|
|
|
, Digit denom
|
|
|
|
, Reciprocal recip
|
|
|
|
, out Digit q
|
|
|
|
, out Digit r
|
|
|
|
) {
|
|
|
|
Digit numHi = Hi(num)
|
|
|
|
, numLo = Lo(num)
|
|
|
|
, qEst = Digit.MaxValue - recip.EstQuotient(numHi, numLo, 0);
|
|
|
|
UInt64 rEst = unchecked(
|
|
|
|
((UInt64)(numHi - denom) << Digit.BitN | numLo)
|
|
|
|
+ (UInt64)qEst * denom
|
|
|
|
);
|
|
|
|
q = unchecked((Digit)(Hi(rEst) - qEst));
|
|
|
|
r = unchecked(Lo(rEst) + (denom & Hi(rEst)));
|
|
|
|
Digit qq, rr;
|
|
|
|
Div(num, denom, out qq, out rr);
|
|
|
|
Debug.Assert(qq == q && rr == r, "internal error");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|