Skip to content

Commit 5190113

Browse files
committed
Preliminary benchmarking drafts
1 parent 708ddab commit 5190113

File tree

4 files changed

+187
-1
lines changed

4 files changed

+187
-1
lines changed

Classes/FCryptoBigInt.uc

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,30 @@ static final function int BitLength(
548548
return (Twk << 4) + BIT_LENGTH(Tw);
549549
}
550550

551+
static final function int BitLength_NonConst(
552+
array<int> X,
553+
int XLen
554+
)
555+
{
556+
local int Tw;
557+
local int Twk;
558+
local int W;
559+
local int C;
560+
561+
Tw = 0;
562+
Twk = 0;
563+
564+
while (XLen-- > 0)
565+
{
566+
C = EQ(Tw, 0);
567+
W = X[XLen];
568+
Tw = MUX(C, W, Tw);
569+
Twk = MUX(C, XLen, Twk);
570+
}
571+
572+
return (Twk << 4) + BIT_LENGTH(Tw);
573+
}
574+
551575
/*
552576
* Decode an integer from its big-endian unsigned representation. The
553577
* integer MUST be lower than m[]; the announced bit length written in
@@ -725,6 +749,46 @@ static final function Decode(
725749
X[0] = BitLength(XArr, V - 1);
726750
}
727751

752+
static final function Decode_NonConst(
753+
out array<int> X,
754+
array<byte> Src,
755+
int Len
756+
)
757+
{
758+
local int V;
759+
local int Acc;
760+
local int AccLen;
761+
local int B;
762+
local array<int> XArr;
763+
764+
V = 1;
765+
Acc = 0;
766+
AccLen = 0;
767+
while (Len-- > 0)
768+
{
769+
B = Src[Len];
770+
// Acc = Acc | ((B << AccLen) & 0xFFFF); // @ALIGN-32-16.
771+
Acc = Acc | (B << AccLen);
772+
AccLen += 8;
773+
if (AccLen >= 15)
774+
{
775+
X[V++] = Acc & 0x7FFF;
776+
AccLen -= 15;
777+
Acc = Acc >>> 15;
778+
}
779+
}
780+
if (AccLen != 0)
781+
{
782+
X[V++] = Acc & 0xFFFF; // @ALIGN-32-16.
783+
}
784+
785+
// X[0] = BitLength(X + 1, V - 1);
786+
// TODO: is there a faster way of doing this in UScript?
787+
XArr = X;
788+
XArr.Remove(0, 1);
789+
X[0] = BitLength_NonConst(XArr, V - 1);
790+
}
791+
728792
/*
729793
* Decode an integer from its big-endian unsigned representation, and
730794
* reduce it modulo the provided modulus m[]. The announced bit length

Classes/FCryptoMacros.uci

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// General development debugging.
22
`define FCDEBUG 1
33

4+
// Define benchmarking functions, data and run the test suite.
5+
`define FCBENCHMARK 1
6+
47
// Monty specific extra debugging.
58
// `define FCDEBUG_MONTY 1
69

Classes/FCryptoQWORD.uc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,18 @@ struct FCQWORD
3434
};
3535

3636
// Return A > B.
37-
final static function bool IsGt(FCQWORD A, FCQWORD B)
37+
final static function bool IsGt(const out FCQWORD A, const out FCQWORD B)
38+
{
39+
if (IsGt_AsUInt32(A.A, B.A))
40+
{
41+
return True;
42+
}
43+
44+
return IsGt_AsUInt32(A.B, B.B);
45+
}
46+
47+
// For benchmarking.
48+
final static function bool IsGt_NonConst(FCQWORD A, FCQWORD B)
3849
{
3950
if (IsGt_AsUInt32(A.A, B.A))
4051
{

Classes/FCryptoTestMutator.uc

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,11 +1060,23 @@ private final simulated function int TestMath()
10601060
local int Remainder;
10611061
local int HardCodedMontyFail;
10621062
local int MontyDecodeResult;
1063+
local int BenchmarkRound;
10631064
local string BigIntString;
10641065
10651066
local int Dummy;
10661067
local FCQWORD QW;
1068+
local FCQWORD QW1;
1069+
local FCQWORD QW2;
1070+
local FCQWORD QW3;
1071+
local FCQWORD QW4;
1072+
local FCQWORD QW5;
1073+
local FCQWORD QW6;
1074+
local FCQWORD QW7;
1075+
local FCQWORD QW8;
1076+
local FCQWORD QW9;
10671077
local bool bQWCarry;
1078+
local float QWClock;
1079+
local int QWIdx;
10681080
10691081
// TODO: Design for FCQWORD arithmetic.
10701082
Dummy = 0xFFFFFFFF;
@@ -1109,6 +1121,70 @@ private final simulated function int TestMath()
11091121
`fclog("0x7FFFFFFF > 0xFFFFFFFF :" @ IsGt(0x7FFFFFFF, 0xFFFFFFFF));
11101122
`fclog("0xFFFFFFFF > 0x7FFFFFFF :" @ IsGt(0xFFFFFFFF, 0x7FFFFFFF));
11111123
1124+
QW1.A = 0x00000000;
1125+
QW1.B = 0xFFFFFFFF;
1126+
QW2.A = 0xFFFFFFFF;
1127+
QW2.B = 0xFFFFFFFF;
1128+
QW3.A = 0x00000000;
1129+
QW3.B = 0x00000000;
1130+
QW4.A = 0x00000000;
1131+
QW4.B = 0xFFFFFFFF;
1132+
QW5.A = 0x00000002;
1133+
QW5.B = 0xFFFFFFFF;
1134+
QW6.A = 0x00000000;
1135+
QW6.B = 0x7FFAFFFF;
1136+
QW7.A = 0x00000000;
1137+
QW7.B = 0x00000002;
1138+
QW8.A = 0x00000000;
1139+
QW8.B = 0x00000001;
1140+
QW9.A = 0x7FFFFFFF;
1141+
QW9.B = 0x7FFFFFFF;
1142+
1143+
Clock(QWClock);
1144+
for (QWIdx = 0; QWIdx < 1024; ++QWIdx)
1145+
{
1146+
class'FCryptoQWORD'.static.IsGt(QW1, QW1);
1147+
class'FCryptoQWORD'.static.IsGt(QW1, QW2);
1148+
class'FCryptoQWORD'.static.IsGt(QW2, QW3);
1149+
class'FCryptoQWORD'.static.IsGt(QW3, QW4);
1150+
class'FCryptoQWORD'.static.IsGt(QW4, QW5);
1151+
class'FCryptoQWORD'.static.IsGt(QW5, QW6);
1152+
class'FCryptoQWORD'.static.IsGt(QW7, QW8);
1153+
class'FCryptoQWORD'.static.IsGt(QW8, QW9);
1154+
class'FCryptoQWORD'.static.IsGt(QW9, QW1);
1155+
class'FCryptoQWORD'.static.IsGt(QW2, QW5);
1156+
class'FCryptoQWORD'.static.IsGt(QW7, QW9);
1157+
class'FCryptoQWORD'.static.IsGt(QW1, QW5);
1158+
class'FCryptoQWORD'.static.IsGt(QW1, QW4);
1159+
class'FCryptoQWORD'.static.IsGt(QW4, QW9);
1160+
class'FCryptoQWORD'.static.IsGt(QW4, QW8);
1161+
}
1162+
UnClock(QWClock);
1163+
`fclog("QWClock (reference)=" $ QWClock);
1164+
1165+
QWClock = 0;
1166+
Clock(QWClock);
1167+
for (QWIdx = 0; QWIdx < 1024; ++QWIdx)
1168+
{
1169+
class'FCryptoQWORD'.static.IsGt_NonConst(QW1, QW1);
1170+
class'FCryptoQWORD'.static.IsGt_NonConst(QW1, QW2);
1171+
class'FCryptoQWORD'.static.IsGt_NonConst(QW2, QW3);
1172+
class'FCryptoQWORD'.static.IsGt_NonConst(QW3, QW4);
1173+
class'FCryptoQWORD'.static.IsGt_NonConst(QW4, QW5);
1174+
class'FCryptoQWORD'.static.IsGt_NonConst(QW5, QW6);
1175+
class'FCryptoQWORD'.static.IsGt_NonConst(QW7, QW8);
1176+
class'FCryptoQWORD'.static.IsGt_NonConst(QW8, QW9);
1177+
class'FCryptoQWORD'.static.IsGt_NonConst(QW9, QW1);
1178+
class'FCryptoQWORD'.static.IsGt_NonConst(QW2, QW5);
1179+
class'FCryptoQWORD'.static.IsGt_NonConst(QW7, QW9);
1180+
class'FCryptoQWORD'.static.IsGt_NonConst(QW1, QW5);
1181+
class'FCryptoQWORD'.static.IsGt_NonConst(QW1, QW4);
1182+
class'FCryptoQWORD'.static.IsGt_NonConst(QW4, QW9);
1183+
class'FCryptoQWORD'.static.IsGt_NonConst(QW4, QW8);
1184+
}
1185+
UnClock(QWClock);
1186+
`fclog("QWClock (copy)=" $ QWClock);
1187+
11121188
// BearSSL assumes all operands caller-allocated.
11131189
// We'll do some bare minimum allocations here to avoid issues.
11141190
// TODO: does UScript dynamic array allocation break CT guarantees?
@@ -1153,6 +1229,38 @@ private final simulated function int TestMath()
11531229
);
11541230
X.Length = 0;
11551231
1232+
// -----------------------------------------------------------------------
1233+
// -----------------------------------------------------------------------
1234+
// TODO: dedicated benchmarking test suite.
1235+
QWClock = 0;
1236+
Clock(QWClock);
1237+
for (BenchmarkRound = 0; BenchmarkRound < 10000; ++BenchmarkRound)
1238+
{
1239+
class'FCryptoBigInt'.static.Decode(
1240+
X,
1241+
Bytes_683384335291162482276352519,
1242+
Bytes_683384335291162482276352519.Length
1243+
);
1244+
}
1245+
UnClock(QWClock);
1246+
`fclog("QWClock (decode1)=" $ QWClock);
1247+
1248+
QWClock = 0;
1249+
Clock(QWClock);
1250+
for (BenchmarkRound = 0; BenchmarkRound < 10000; ++BenchmarkRound)
1251+
{
1252+
class'FCryptoBigInt'.static.Decode_NonConst(
1253+
X,
1254+
Bytes_683384335291162482276352519,
1255+
Bytes_683384335291162482276352519.Length
1256+
);
1257+
}
1258+
UnClock(QWClock);
1259+
`fclog("QWClock (decode2)=" $ QWClock);
1260+
1261+
// -----------------------------------------------------------------------
1262+
// -----------------------------------------------------------------------
1263+
11561264
`fcdebug("check decode Bytes_683384335291162482276352519");
11571265
class'FCryptoBigInt'.static.Decode(
11581266
X,

0 commit comments

Comments
 (0)