Skip to content

Commit 908c22d

Browse files
committed
QWORD prototyping
1 parent 1789d44 commit 908c22d

File tree

4 files changed

+209
-45
lines changed

4 files changed

+209
-45
lines changed

Classes/FCryptoQWORD.uc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright (c) 2024 Tuomo Kriikkula <tuokri@tuta.io>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining
5+
* a copy of this software and associated documentation files (the
6+
* "Software"), to deal in the Software without restriction, including
7+
* without limitation the rights to use, copy, modify, merge, publish,
8+
* distribute, sublicense, and/or sell copies of the Software, and to
9+
* permit persons to whom the Software is furnished to do so, subject to
10+
* the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be
13+
* included in all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
class FCryptoQWORD extends Object
26+
abstract
27+
notplaceable;
28+
29+
// 64-bit integer simulated as two 32-bit integers.
30+
struct FCQWORD
31+
{
32+
var int A; // High.
33+
var int B; // Low.
34+
};
35+
36+
// Return A > B.
37+
final static function bool IsGt(FCQWORD A, 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+
// Interpret A and B as unsigned 32-bit integers and return A > B.
48+
final static function bool IsGt_AsUInt32(int A, int B)
49+
{
50+
local int Ltb;
51+
local int Gtb;
52+
53+
// All bits in A that are less than their corresponding bits in B.
54+
Ltb = ~A & B;
55+
56+
// All bits in A that are greater than their corresponding bits in B.
57+
Gtb = A & ~B;
58+
59+
Ltb = Ltb | (Ltb >>> 1);
60+
Ltb = Ltb | (Ltb >>> 2);
61+
Ltb = Ltb | (Ltb >>> 4);
62+
Ltb = Ltb | (Ltb >>> 8);
63+
Ltb = Ltb | (Ltb >>> 16);
64+
65+
// A > B --> non-zero.
66+
// A <= B --> zero.
67+
return bool(Gtb & ~Ltb);
68+
}

Classes/FCryptoSHA2.uc

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class FCryptoSHA2 extends Object;
4040
var const array<int> SHA224_IV;
4141
var const array<int> SHA256_IV;
4242
var const array<int> K_SMALL;
43-
// var const array<QWORD> K_BIG; // TODO
43+
var const array<FCQWORD> K_BIG;
4444

4545
static final function Sha2SmallRound(
4646
const out array<byte> Buf,
@@ -343,47 +343,46 @@ DefaultProperties
343343
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
344344
)}
345345

346-
// TODO: QWORDs needed?
347-
// K_BIG={(
348-
// 0x428A2F98D728AE22, 0x7137449123EF65CD,
349-
// 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC,
350-
// 0x3956C25BF348B538, 0x59F111F1B605D019,
351-
// 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118,
352-
// 0xD807AA98A3030242, 0x12835B0145706FBE,
353-
// 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2,
354-
// 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1,
355-
// 0x9BDC06A725C71235, 0xC19BF174CF692694,
356-
// 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3,
357-
// 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65,
358-
// 0x2DE92C6F592B0275, 0x4A7484AA6EA6E483,
359-
// 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5,
360-
// 0x983E5152EE66DFAB, 0xA831C66D2DB43210,
361-
// 0xB00327C898FB213F, 0xBF597FC7BEEF0EE4,
362-
// 0xC6E00BF33DA88FC2, 0xD5A79147930AA725,
363-
// 0x06CA6351E003826F, 0x142929670A0E6E70,
364-
// 0x27B70A8546D22FFC, 0x2E1B21385C26C926,
365-
// 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF,
366-
// 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8,
367-
// 0x81C2C92E47EDAEE6, 0x92722C851482353B,
368-
// 0xA2BFE8A14CF10364, 0xA81A664BBC423001,
369-
// 0xC24B8B70D0F89791, 0xC76C51A30654BE30,
370-
// 0xD192E819D6EF5218, 0xD69906245565A910,
371-
// 0xF40E35855771202A, 0x106AA07032BBD1B8,
372-
// 0x19A4C116B8D2D0C8, 0x1E376C085141AB53,
373-
// 0x2748774CDF8EEB99, 0x34B0BCB5E19B48A8,
374-
// 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB,
375-
// 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3,
376-
// 0x748F82EE5DEFB2FC, 0x78A5636F43172F60,
377-
// 0x84C87814A1F0AB72, 0x8CC702081A6439EC,
378-
// 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9,
379-
// 0xBEF9A3F7B2C67915, 0xC67178F2E372532B,
380-
// 0xCA273ECEEA26619C, 0xD186B8C721C0C207,
381-
// 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178,
382-
// 0x06F067AA72176FBA, 0x0A637DC5A2C898A6,
383-
// 0x113F9804BEF90DAE, 0x1B710B35131C471B,
384-
// 0x28DB77F523047D84, 0x32CAAB7B40C72493,
385-
// 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C,
386-
// 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A,
387-
// 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
388-
// )}
346+
K_BIG={(
347+
(A=0x428A2F98, B=0xD728AE22), (A=0x71374491, B=0x23EF65CD),
348+
(A=0xB5C0FBCF, B=0xEC4D3B2F), (A=0xE9B5DBA5, B=0x8189DBBC),
349+
(A=0x3956C25B, B=0xF348B538), (A=0x59F111F1, B=0xB605D019),
350+
(A=0x923F82A4, B=0xAF194F9B), (A=0xAB1C5ED5, B=0xDA6D8118),
351+
(A=0xD807AA98, B=0xA3030242), (A=0x12835B01, B=0x45706FBE),
352+
(A=0x243185BE, B=0x4EE4B28C), (A=0x550C7DC3, B=0xD5FFB4E2),
353+
(A=0x72BE5D74, B=0xF27B896F), (A=0x80DEB1FE, B=0x3B1696B1),
354+
(A=0x9BDC06A7, B=0x25C71235), (A=0xC19BF174, B=0xCF692694),
355+
(A=0xE49B69C1, B=0x9EF14AD2), (A=0xEFBE4786, B=0x384F25E3),
356+
(A=0x0FC19DC6, B=0x8B8CD5B5), (A=0x240CA1CC, B=0x77AC9C65),
357+
(A=0x2DE92C6F, B=0x592B0275), (A=0x4A7484AA, B=0x6EA6E483),
358+
(A=0x5CB0A9DC, B=0xBD41FBD4), (A=0x76F988DA, B=0x831153B5),
359+
(A=0x983E5152, B=0xEE66DFAB), (A=0xA831C66D, B=0x2DB43210),
360+
(A=0xB00327C8, B=0x98FB213F), (A=0xBF597FC7, B=0xBEEF0EE4),
361+
(A=0xC6E00BF3, B=0x3DA88FC2), (A=0xD5A79147, B=0x930AA725),
362+
(A=0x06CA6351, B=0xE003826F), (A=0x14292967, B=0x0A0E6E70),
363+
(A=0x27B70A85, B=0x46D22FFC), (A=0x2E1B2138, B=0x5C26C926),
364+
(A=0x4D2C6DFC, B=0x5AC42AED), (A=0x53380D13, B=0x9D95B3DF),
365+
(A=0x650A7354, B=0x8BAF63DE), (A=0x766A0ABB, B=0x3C77B2A8),
366+
(A=0x81C2C92E, B=0x47EDAEE6), (A=0x92722C85, B=0x1482353B),
367+
(A=0xA2BFE8A1, B=0x4CF10364), (A=0xA81A664B, B=0xBC423001),
368+
(A=0xC24B8B70, B=0xD0F89791), (A=0xC76C51A3, B=0x0654BE30),
369+
(A=0xD192E819, B=0xD6EF5218), (A=0xD6990624, B=0x5565A910),
370+
(A=0xF40E3585, B=0x5771202A), (A=0x106AA070, B=0x32BBD1B8),
371+
(A=0x19A4C116, B=0xB8D2D0C8), (A=0x1E376C08, B=0x5141AB53),
372+
(A=0x2748774C, B=0xDF8EEB99), (A=0x34B0BCB5, B=0xE19B48A8),
373+
(A=0x391C0CB3, B=0xC5C95A63), (A=0x4ED8AA4A, B=0xE3418ACB),
374+
(A=0x5B9CCA4F, B=0x7763E373), (A=0x682E6FF3, B=0xD6B2B8A3),
375+
(A=0x748F82EE, B=0x5DEFB2FC), (A=0x78A5636F, B=0x43172F60),
376+
(A=0x84C87814, B=0xA1F0AB72), (A=0x8CC70208, B=0x1A6439EC),
377+
(A=0x90BEFFFA, B=0x23631E28), (A=0xA4506CEB, B=0xDE82BDE9),
378+
(A=0xBEF9A3F7, B=0xB2C67915), (A=0xC67178F2, B=0xE372532B),
379+
(A=0xCA273ECE, B=0xEA26619C), (A=0xD186B8C7, B=0x21C0C207),
380+
(A=0xEADA7DD6, B=0xCDE0EB1E), (A=0xF57D4F7F, B=0xEE6ED178),
381+
(A=0x06F067AA, B=0x72176FBA), (A=0x0A637DC5, B=0xA2C898A6),
382+
(A=0x113F9804, B=0xBEF90DAE), (A=0x1B710B35, B=0x131C471B),
383+
(A=0x28DB77F5, B=0x23047D84), (A=0x32CAAB7B, B=0x40C72493),
384+
(A=0x3C9EBE0A, B=0x15C9BEBC), (A=0x431D67C4, B=0x9C100D4C),
385+
(A=0x4CC5D4BE, B=0xCB3E42B6), (A=0x597F299C, B=0xFC657E2A),
386+
(A=0x5FCB6FAB, B=0x3AD6FAEC), (A=0x6C44198C, B=0x4A475817)
387+
)}
389388
}

Classes/FCryptoTestMutator.uc

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,43 @@ private final simulated function int TestOperations()
990990
`endif
991991
}
992992
993+
// TODO: prototyping.
994+
final static function bool IsEq(int A, int B)
995+
{
996+
local int C;
997+
998+
C = A ^ B;
999+
C = C | (C >>> 16);
1000+
C = C | (C >>> 8);
1001+
C = C | (C >>> 4);
1002+
C = C | (C >>> 2);
1003+
C = C | (C >>> 1);
1004+
return bool(-(C & 1));
1005+
}
1006+
1007+
// TODO: prototyping.
1008+
final static function bool IsGt(int A, int B)
1009+
{
1010+
local int Ltb;
1011+
local int Gtb;
1012+
1013+
// These are all the bits in a that are less than their corresponding bits in b.
1014+
Ltb = ~A & B;
1015+
1016+
// These are all the bits in a that are greater than their corresponding bits in b.
1017+
Gtb = A & ~B;
1018+
1019+
Ltb = Ltb | (Ltb >>> 1);
1020+
Ltb = Ltb | (Ltb >>> 2);
1021+
Ltb = Ltb | (Ltb >>> 4);
1022+
Ltb = Ltb | (Ltb >>> 8);
1023+
Ltb = Ltb | (Ltb >>> 16);
1024+
1025+
// Nonzero if a > b
1026+
// Zero if a <= b
1027+
return bool(Gtb & ~Ltb);
1028+
}
1029+
9931030
// Mirrors most of the tests from BearSSL's test_match.c,
9941031
// with some UnrealScript-specific additions.
9951032
private final simulated function int TestMath()
@@ -1026,15 +1063,52 @@ private final simulated function int TestMath()
10261063
local string BigIntString;
10271064
10281065
local int Dummy;
1066+
local FCQWORD QW;
1067+
local bool bQWCarry;
10291068
1030-
// TODO: Design for QWORD arithmetic.
1069+
// TODO: Design for FCQWORD arithmetic.
10311070
Dummy = 0xFFFFFFFF;
10321071
`fclog("Dummy=" $ Dummy);
10331072
`fclog("Dummy=" $ ToHex(Dummy));
10341073
Dummy += 0xF;
10351074
`fclog("Dummy=" $ Dummy);
10361075
`fclog("Dummy=" $ ToHex(Dummy));
10371076
1077+
QW.A = 0x00000000;
1078+
QW.B = 0xFFFFFFFF;
1079+
QW.B += 0xF;
1080+
`fclog("QW.B=" $ QW.B);
1081+
`fclog("QW.B=" $ ToHex(QW.B));
1082+
bQWCarry = QW.B < 0xFFFFFFFF; // TODO: might need a bitwise check for this?
1083+
`fclog("bQWCarry=" $ bQWCarry);
1084+
1085+
QW.B = MaxInt;
1086+
QW.B += 0xF;
1087+
`fclog("QW.B=" $ QW.B);
1088+
`fclog("QW.B=" $ ToHex(QW.B));
1089+
bQWCarry = QW.B < 0xFFFFFFFF; // TODO: might need a bitwise check for this?
1090+
`fclog("bQWCarry=" $ bQWCarry);
1091+
1092+
`fclog("0x00000000 == 0xFFFFFFFF :" @ IsEq(0x00000000, 0xFFFFFFFF));
1093+
`fclog("0xFFFFFFFF == 0xFFFFFFFF :" @ IsEq(0xFFFFFFFF, 0xFFFFFFFF));
1094+
`fclog("0x00000000 == 0x00000000 :" @ IsEq(0x00000000, 0x00000000));
1095+
`fclog("0x7FFFFFFF == 0x00000000 :" @ IsEq(0x7FFFFFFF, 0x00000000));
1096+
`fclog("0x00000000 == 0x7FFFFFFF :" @ IsEq(0x00000000, 0x7FFFFFFF));
1097+
`fclog("0x00000001 == 0x00000002 :" @ IsEq(0x00000001, 0x00000002));
1098+
`fclog("0x00000002 == 0x00000001 :" @ IsEq(0x00000002, 0x00000001));
1099+
`fclog("0x7FFFFFFF == 0xFFFFFFFF :" @ IsEq(0x7FFFFFFF, 0xFFFFFFFF));
1100+
`fclog("0xFFFFFFFF == 0x7FFFFFFF :" @ IsEq(0xFFFFFFFF, 0x7FFFFFFF));
1101+
1102+
`fclog("0x00000000 > 0xFFFFFFFF :" @ IsGt(0x00000000, 0xFFFFFFFF));
1103+
`fclog("0xFFFFFFFF > 0xFFFFFFFF :" @ IsGt(0xFFFFFFFF, 0xFFFFFFFF));
1104+
`fclog("0x00000000 > 0x00000000 :" @ IsGt(0x00000000, 0x00000000));
1105+
`fclog("0x7FFFFFFF > 0x00000000 :" @ IsGt(0x7FFFFFFF, 0x00000000));
1106+
`fclog("0x00000000 > 0x7FFFFFFF :" @ IsGt(0x00000000, 0x7FFFFFFF));
1107+
`fclog("0x00000001 > 0x00000002 :" @ IsGt(0x00000001, 0x00000002));
1108+
`fclog("0x00000002 > 0x00000001 :" @ IsGt(0x00000002, 0x00000001));
1109+
`fclog("0x7FFFFFFF > 0xFFFFFFFF :" @ IsGt(0x7FFFFFFF, 0xFFFFFFFF));
1110+
`fclog("0xFFFFFFFF > 0x7FFFFFFF :" @ IsGt(0xFFFFFFFF, 0x7FFFFFFF));
1111+
10381112
// BearSSL assumes all operands caller-allocated.
10391113
// We'll do some bare minimum allocations here to avoid issues.
10401114
// TODO: does UScript dynamic array allocation break CT guarantees?

Classes/FCryptoUtils.uc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,26 @@ static final function bool FromHex(string HexString, out int Result)
8888
Result = Res;
8989
return True;
9090
}
91+
92+
// TODO: just use BytesFromHex from FCryptoBigInt? And move it here?
93+
/*
94+
* Decode a hexadecimal string. Returned value is the number of decoded
95+
* bytes.
96+
*/
97+
// static final function int HexToBin(out string Dst, string Src)
98+
// {
99+
// local int Num;
100+
// local int Acc;
101+
// local int Z;
102+
103+
// Num = 0;
104+
// Z = 0;
105+
// Acc = 0;
106+
107+
// while (False)
108+
// {
109+
110+
// }
111+
112+
// return Num;
113+
// }

0 commit comments

Comments
 (0)