mirror of
https://github.com/Neo-Desktop/WindowsXPKg
synced 2024-11-22 05:41:01 +02:00
refactor/rework confid
This commit is contained in:
parent
72d48dd38b
commit
8cc691b72f
2
.idea/UMSKT.iml
Normal file
2
.idea/UMSKT.iml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
90
.idea/editor.xml
Normal file
90
.idea/editor.xml
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="BackendCodeEditorSettings">
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/FREE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/UMSKT.iml" filepath="$PROJECT_DIR$/.idea/UMSKT.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -185,7 +185,7 @@ CPMAddPackage(
|
|||||||
### Resource compilation
|
### Resource compilation
|
||||||
CMRC_ADD_RESOURCE_LIBRARY(umskt-rc ALIAS umskt::rc NAMESPACE umskt keys.json)
|
CMRC_ADD_RESOURCE_LIBRARY(umskt-rc ALIAS umskt::rc NAMESPACE umskt keys.json)
|
||||||
|
|
||||||
SET(LIBUMSKT_SRC src/libumskt/libumskt.cpp src/libumskt/pidgen3/BINK1998.cpp src/libumskt/pidgen3/BINK2002.cpp src/libumskt/pidgen3/key.cpp src/libumskt/pidgen3/util.cpp src/libumskt/confid/confid.cpp src/libumskt/pidgen2/PIDGEN2.cpp src/libumskt/debugoutput.cpp)
|
SET(LIBUMSKT_SRC src/libumskt/libumskt.cpp src/libumskt/pidgen3/BINK1998.cpp src/libumskt/pidgen3/BINK2002.cpp src/libumskt/pidgen3/key.cpp src/libumskt/pidgen3/util.cpp src/libumskt/confid/confid.cpp src/libumskt/confid/polynomial.cpp src/libumskt/confid/residue.cpp src/libumskt/confid/divisor.cpp src/libumskt/pidgen2/PIDGEN2.cpp src/libumskt/debugoutput.cpp)
|
||||||
|
|
||||||
#### Separate Build Path for emscripten
|
#### Separate Build Path for emscripten
|
||||||
IF (EMSCRIPTEN)
|
IF (EMSCRIPTEN)
|
||||||
|
167
keys.json
167
keys.json
@ -93,6 +93,9 @@
|
|||||||
"Plus! Digital Media Edition for Windows XP": {
|
"Plus! Digital Media Edition for Windows XP": {
|
||||||
"BINK": ["52", "53"]
|
"BINK": ["52", "53"]
|
||||||
},
|
},
|
||||||
|
"Rise of Nations - Rise of Legends": {
|
||||||
|
"BINK": ["52", "53"]
|
||||||
|
},
|
||||||
"Windows Longhorn (6.0.4033.0)": {
|
"Windows Longhorn (6.0.4033.0)": {
|
||||||
"BINK": ["54", "55"]
|
"BINK": ["54", "55"]
|
||||||
},
|
},
|
||||||
@ -1532,6 +1535,11 @@
|
|||||||
},
|
},
|
||||||
"Activation": {
|
"Activation": {
|
||||||
"Windows XP": {
|
"Windows XP": {
|
||||||
|
"flags": {
|
||||||
|
"XPBrand": true,
|
||||||
|
"Office": false,
|
||||||
|
"version": 0
|
||||||
|
},
|
||||||
"p": "102011604035381881",
|
"p": "102011604035381881",
|
||||||
"x": {
|
"x": {
|
||||||
"0": "0",
|
"0": "0",
|
||||||
@ -1543,23 +1551,55 @@
|
|||||||
},
|
},
|
||||||
"mul": "65537",
|
"mul": "65537",
|
||||||
"priv": "1315384396487572637498562978064321",
|
"priv": "1315384396487572637498562978064321",
|
||||||
"iid_key": "1791516372"
|
"iid_key": "6AC85ED4",
|
||||||
|
"non_residue": "43",
|
||||||
|
"mod_constants": {
|
||||||
|
"0": "0x604FA6A1C6346A87",
|
||||||
|
"1": "0x2D351C6D04F8B",
|
||||||
|
"2": "0x604FA6A1C6346A87",
|
||||||
|
"3": "0x2D351C6D04F8B"
|
||||||
},
|
},
|
||||||
"Windows XP Plus! Digital Media Edition": {
|
"verification": {
|
||||||
"p": "101996933280717187",
|
"low": "351874082296375233",
|
||||||
|
"hi": "71307131016268"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Whistler": {
|
||||||
|
"flags": {
|
||||||
|
"XPBrand": false,
|
||||||
|
"Office": false,
|
||||||
|
"version": 1
|
||||||
|
},
|
||||||
|
"p": "102413083413401507",
|
||||||
"x": {
|
"x": {
|
||||||
"0": "14442243999705614",
|
"0": "0",
|
||||||
"1": "88154401999011195",
|
"1": "62766224015201615",
|
||||||
"2": "86996763276881336",
|
"2": "45663410017725669",
|
||||||
"3": "95455813375647760",
|
"3": "38799131826419821",
|
||||||
"4": "6252462837094107",
|
"4": "57597400967455908",
|
||||||
"5": "1"
|
"5": "1"
|
||||||
},
|
},
|
||||||
"mul": "65537",
|
"mul": "",
|
||||||
"priv": "2752030625102368166730185283969067",
|
"priv": "",
|
||||||
"iid_key": "1791516372"
|
"iid_key": "6AC85ED4",
|
||||||
|
"non_residue": "2",
|
||||||
|
"mod_constants": {
|
||||||
|
"0": "",
|
||||||
|
"1": "",
|
||||||
|
"2": "",
|
||||||
|
"3": ""
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"low": "",
|
||||||
|
"hi": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Office XP": {
|
||||||
|
"flags": {
|
||||||
|
"XPBrand": true,
|
||||||
|
"Office": true,
|
||||||
|
"version": 1
|
||||||
},
|
},
|
||||||
"Office XP / Office 2003": {
|
|
||||||
"p": "103099955908255721",
|
"p": "103099955908255721",
|
||||||
"x": {
|
"x": {
|
||||||
"0": "0",
|
"0": "0",
|
||||||
@ -1571,7 +1611,108 @@
|
|||||||
},
|
},
|
||||||
"mul": "65537",
|
"mul": "65537",
|
||||||
"priv": "10294349293510589382098112327865153",
|
"priv": "10294349293510589382098112327865153",
|
||||||
"iid_key": "1513142771"
|
"iid_key": "5A30B9F3",
|
||||||
|
"non_residue": "3",
|
||||||
|
"mod_constants": {
|
||||||
|
"0": "0x4FA8E4A40CDAE44A",
|
||||||
|
"1": "0x2CBAF12A59BBE",
|
||||||
|
"2": "0x4FA8E4A40CDAE44A",
|
||||||
|
"3": "0x2CBAF12A59BBE"
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"low": "17284868327322833729",
|
||||||
|
"hi": "558057793417439"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Office 2003": {
|
||||||
|
"flags": {
|
||||||
|
"XPBrand": false,
|
||||||
|
"Office": true,
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"p": "103099955908255721",
|
||||||
|
"x": {
|
||||||
|
"0": "0",
|
||||||
|
"1": "64728167274549202",
|
||||||
|
"2": "4488766805843809",
|
||||||
|
"3": "70698430483539942",
|
||||||
|
"4": "64728167274549202",
|
||||||
|
"5": "1"
|
||||||
|
},
|
||||||
|
"mul": "65537",
|
||||||
|
"priv": "10294349293510589382098112327865153",
|
||||||
|
"iid_key": "5A30B9F3",
|
||||||
|
"non_residue": "3",
|
||||||
|
"mod_constants": {
|
||||||
|
"0": "0x4FA8E4A40CDAE44A",
|
||||||
|
"1": "0x2CBAF12A59BBE",
|
||||||
|
"2": "0x4FA8E4A40CDAE44A",
|
||||||
|
"3": "0x2CBAF12A59BBE"
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"low": "17284868327322833729",
|
||||||
|
"hi": "558057793417439"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Office 2007": {
|
||||||
|
"flags": {
|
||||||
|
"XPBrand": false,
|
||||||
|
"Office": true,
|
||||||
|
"version": 4
|
||||||
|
},
|
||||||
|
"p": "103099955908255721",
|
||||||
|
"x": {
|
||||||
|
"0": "0",
|
||||||
|
"1": "64728167274549202",
|
||||||
|
"2": "4488766805843809",
|
||||||
|
"3": "70698430483539942",
|
||||||
|
"4": "64728167274549202",
|
||||||
|
"5": "1"
|
||||||
|
},
|
||||||
|
"mul": "65537",
|
||||||
|
"priv": "10294349293510589382098112327865153",
|
||||||
|
"iid_key": "5A30B9F3",
|
||||||
|
"non_residue": "3",
|
||||||
|
"mod_constants": {
|
||||||
|
"0": "0x4FA8E4A40CDAE44A",
|
||||||
|
"1": "0x2CBAF12A59BBE",
|
||||||
|
"2": "0x4FA8E4A40CDAE44A",
|
||||||
|
"3": "0x2CBAF12A59BBE"
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"low": "17284868327322833729",
|
||||||
|
"hi": "558057793417439"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Plus! Digital Media Edition for Windows XP": {
|
||||||
|
"flags": {
|
||||||
|
"XPBrand": true,
|
||||||
|
"Office": false,
|
||||||
|
"version": 4
|
||||||
|
},
|
||||||
|
"p": "101996933280717187",
|
||||||
|
"x": {
|
||||||
|
"0": "14442243999705614",
|
||||||
|
"1": "88154401999011195",
|
||||||
|
"2": "86996763276881336",
|
||||||
|
"3": "95455813375647760",
|
||||||
|
"4": "6252462837094107",
|
||||||
|
"5": "1"
|
||||||
|
},
|
||||||
|
"mul": "65537",
|
||||||
|
"priv": "2752030625102368166730185283969067",
|
||||||
|
"iid_key": "6AC85ED4",
|
||||||
|
"non_residue": "2",
|
||||||
|
"mod_constants": {
|
||||||
|
"0": "0x2C5C4D3654A594F0",
|
||||||
|
"1": "0x2D36C691A4EA5",
|
||||||
|
"2": "0x2C5C4D3654A594F0",
|
||||||
|
"3": "0x2D36C691A4EA5"
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"low": "8953812210935468417",
|
||||||
|
"hi": "499255905936912"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
src/cli.cpp
11
src/cli.cpp
@ -253,7 +253,7 @@ int CLI::validateCommandLine(Options* options, char *argv[], json *keys) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options->list) {
|
if (options->list) {
|
||||||
for (auto el : (*keys)["Products"].items()) {
|
for (auto const el : (*keys)["Products"].items()) {
|
||||||
int id;
|
int id;
|
||||||
sscanf((el.value()["BINK"][0]).get<std::string>().c_str(), "%x", &id);
|
sscanf((el.value()["BINK"][0]).get<std::string>().c_str(), "%x", &id);
|
||||||
std::cout << el.key() << ": " << el.value()["BINK"] << std::endl;
|
std::cout << el.key() << ": " << el.value()["BINK"] << std::endl;
|
||||||
@ -464,9 +464,11 @@ int CLI::BINK1998Generate() {
|
|||||||
if (this->options.verbose) {
|
if (this->options.verbose) {
|
||||||
fmt::print("\nSuccess count: {}/{}", this->count, this->total);
|
fmt::print("\nSuccess count: {}/{}", this->count, this->total);
|
||||||
}
|
}
|
||||||
if (this->options.nonewlines == false) {
|
|
||||||
|
if (!options.nonewlines) {
|
||||||
fmt::print("\n");
|
fmt::print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,7 +514,8 @@ int CLI::BINK2002Generate() {
|
|||||||
if (this->options.verbose) {
|
if (this->options.verbose) {
|
||||||
fmt::print("\nSuccess count: {}/{}", this->count, this->total);
|
fmt::print("\nSuccess count: {}/{}", this->count, this->total);
|
||||||
}
|
}
|
||||||
if (this->options.nonewlines == false) {
|
|
||||||
|
if (!this->options.nonewlines) {
|
||||||
fmt::print("\n");
|
fmt::print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +591,7 @@ int CLI::ConfirmationID() {
|
|||||||
|
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
fmt::print(confirmation_id);
|
fmt::print(confirmation_id);
|
||||||
if (this->options.nonewlines == false) {
|
if (!this->options.nonewlines) {
|
||||||
fmt::print("\n");
|
fmt::print("\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -36,14 +36,6 @@
|
|||||||
|
|
||||||
CMRC_DECLARE(umskt);
|
CMRC_DECLARE(umskt);
|
||||||
|
|
||||||
enum ACTIVATION_ALGORITHM {
|
|
||||||
WINDOWS = 0,
|
|
||||||
OFFICE_XP = 1,
|
|
||||||
OFFICE_2K3 = 2,
|
|
||||||
OFFICE_2K7 = 3,
|
|
||||||
PLUS_DME = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MODE {
|
enum MODE {
|
||||||
MODE_BINK1998_GENERATE = 0,
|
MODE_BINK1998_GENERATE = 0,
|
||||||
MODE_BINK2002_GENERATE = 1,
|
MODE_BINK2002_GENERATE = 1,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -26,48 +26,128 @@
|
|||||||
#include "../libumskt.h"
|
#include "../libumskt.h"
|
||||||
|
|
||||||
// Confirmation ID generator constants
|
// Confirmation ID generator constants
|
||||||
#define SUCCESS 0
|
enum CONFIRMATION_ID_STATUS {
|
||||||
#define ERR_TOO_SHORT 1
|
SUCCESS = 0,
|
||||||
#define ERR_TOO_LARGE 2
|
ERR_TOO_SHORT = 1,
|
||||||
#define ERR_INVALID_CHARACTER 3
|
ERR_TOO_LARGE = 2,
|
||||||
#define ERR_INVALID_CHECK_DIGIT 4
|
ERR_INVALID_CHARACTER = 3,
|
||||||
#define ERR_UNKNOWN_VERSION 5
|
ERR_INVALID_CHECK_DIGIT = 4,
|
||||||
#define ERR_UNLUCKY 6
|
ERR_UNKNOWN_VERSION = 5,
|
||||||
|
ERR_UNLUCKY = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BAD 0xFFFFFFFFFFFFFFFFull
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
QWORD u[2];
|
QWORD u[2];
|
||||||
QWORD v[2];
|
QWORD v[2];
|
||||||
} TDivisor;
|
} TDivisor;
|
||||||
|
|
||||||
EXPORT class ConfirmationID {
|
enum ACTIVATION_ALGORITHM {
|
||||||
static int calculateCheckDigit(int pid);
|
WINDOWS = 0,
|
||||||
static QWORD residue_add(QWORD x, QWORD y);
|
OFFICE_XP = 1,
|
||||||
static QWORD residue_sub(QWORD x, QWORD y);
|
OFFICE_2K3 = 2,
|
||||||
static QWORD __umul128(QWORD a, QWORD b, QWORD* hi);
|
OFFICE_2K7 = 3,
|
||||||
static QWORD ui128_quotient_mod(QWORD lo, QWORD hi);
|
PLUS_DME = 4,
|
||||||
static QWORD residue_mul(QWORD x, QWORD y);
|
|
||||||
static QWORD residue_pow(QWORD x, QWORD y);
|
|
||||||
static QWORD inverse(QWORD u, QWORD v);
|
|
||||||
static QWORD residue_inv(QWORD x);
|
|
||||||
static QWORD residue_sqrt(QWORD what);
|
|
||||||
static int find_divisor_v(TDivisor* d);
|
|
||||||
static int polynomial_mul(int adeg, const QWORD a[], int bdeg, const QWORD b[], int resultprevdeg, QWORD result[]);
|
|
||||||
static int polynomial_div_monic(int adeg, QWORD a[], int bdeg, const QWORD b[], QWORD* quotient);
|
|
||||||
static void polynomial_xgcd(int adeg, const QWORD a[3], int bdeg, const QWORD b[3], int* pgcddeg, QWORD gcd[3], int* pmult1deg, QWORD mult1[3], int* pmult2deg, QWORD mult2[3]);
|
|
||||||
static int u2poly(const TDivisor* src, QWORD polyu[3], QWORD polyv[2]);
|
|
||||||
static void divisor_add(const TDivisor* src1, const TDivisor* src2, TDivisor* dst);
|
|
||||||
static void divisor_mul(const TDivisor* src, QWORD mult, TDivisor* dst);
|
|
||||||
static void divisor_mul128(const TDivisor* src, QWORD mult_lo, QWORD mult_hi, TDivisor* dst);
|
|
||||||
static unsigned rol(unsigned x, int shift);
|
|
||||||
static void sha1_single_block(unsigned char input[64], unsigned char output[20]);
|
|
||||||
static void decode_iid_new_version(unsigned char* iid, unsigned char* hwid, int* version);
|
|
||||||
static void Mix(unsigned char* buffer, size_t bufSize, const unsigned char* key, size_t keySize);
|
|
||||||
static void Unmix(unsigned char* buffer, size_t bufSize, const unsigned char* key, size_t keySize);
|
|
||||||
|
|
||||||
public:
|
|
||||||
static int Generate(const char* installation_id_str, char confirmation_id[49], int mode, std::string productid);
|
|
||||||
//EXPORT static int CLIRun();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EXPORT class ConfirmationID {
|
||||||
|
QWORD MOD = 0, NON_RESIDUE = 0;
|
||||||
|
QWORD f[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
|
||||||
|
QWORD p[4] = { 0x0, 0x0, 0x0, 0x0 };
|
||||||
|
QWORD u[2] = { 0x0, 0x0 };
|
||||||
|
|
||||||
|
unsigned char iid_key[4] = { 0x0, 0x0, 0x0, 0x0};
|
||||||
|
BOOL isOffice = false, isXPBrand = false;
|
||||||
|
unsigned flagVersion = 0;
|
||||||
|
public:
|
||||||
|
void setFlagVersion(unsigned int flagVersion);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int calculateCheckDigit(int pid);
|
||||||
|
void decode_iid_new_version(unsigned char* iid, unsigned char* hwid, int* version);
|
||||||
|
void Mix(unsigned char* buffer, size_t bufSize, const unsigned char* key, size_t keySize);
|
||||||
|
void Unmix(unsigned char* buffer, size_t bufSize, const unsigned char* key, size_t keySize);
|
||||||
|
|
||||||
|
friend class Residue;
|
||||||
|
Residue *residue;
|
||||||
|
|
||||||
|
friend class Polynomial;
|
||||||
|
Polynomial *polynomial;
|
||||||
|
|
||||||
|
friend class Divisor;
|
||||||
|
Divisor *divisor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int Generate(const char* installation_id_str, char confirmation_id[49], std::string productid);
|
||||||
|
|
||||||
|
void setMod(QWORD mod);
|
||||||
|
void setNonResidue(QWORD nonResidue);
|
||||||
|
void setPValues(QWORD p0, QWORD p1, QWORD p2, QWORD p3);
|
||||||
|
void setPValues(QWORD pValues[4]);
|
||||||
|
void setFValues(QWORD f0, QWORD f1, QWORD f2, QWORD f3, QWORD f4, QWORD f5);
|
||||||
|
void setFValues(QWORD fValues[6]);
|
||||||
|
void setIsOffice(BOOL isOffice);
|
||||||
|
void setIsXPBrand(BOOL isXpBrand);
|
||||||
|
|
||||||
|
ConfirmationID() {
|
||||||
|
residue = new Residue(this);
|
||||||
|
polynomial = new Polynomial(this);
|
||||||
|
divisor = new Divisor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ConfirmationID() {
|
||||||
|
delete residue, polynomial, divisor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Residue {
|
||||||
|
ConfirmationID *parent;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Residue(ConfirmationID *in) {
|
||||||
|
parent = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD add(QWORD x, QWORD y);
|
||||||
|
QWORD sub(QWORD x, QWORD y);
|
||||||
|
QWORD __umul128(QWORD a, QWORD b, QWORD* hi);
|
||||||
|
QWORD ui128_quotient_mod(QWORD lo, QWORD hi);
|
||||||
|
QWORD mul(QWORD x, QWORD y);
|
||||||
|
QWORD pow(QWORD x, QWORD y);
|
||||||
|
QWORD inverse(QWORD u, QWORD v);
|
||||||
|
QWORD inv(QWORD x);
|
||||||
|
QWORD sqrt(QWORD what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Polynomial {
|
||||||
|
ConfirmationID *parent;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Polynomial(ConfirmationID *in) {
|
||||||
|
parent = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mul(int adeg, const QWORD a[], int bdeg, const QWORD b[], int resultprevdeg, QWORD result[]);
|
||||||
|
int div_monic(int adeg, QWORD a[], int bdeg, const QWORD b[], QWORD* quotient);
|
||||||
|
void xgcd(int adeg, const QWORD a[3], int bdeg, const QWORD b[3], int* pgcddeg, QWORD gcd[3], int* pmult1deg, QWORD mult1[3], int* pmult2deg, QWORD mult2[3]);
|
||||||
|
int u2poly(const TDivisor* src, QWORD polyu[3], QWORD polyv[2]);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Divisor {
|
||||||
|
ConfirmationID *parent;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Divisor(ConfirmationID *in) {
|
||||||
|
parent = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_divisor_v(TDivisor* d);
|
||||||
|
void add(const TDivisor* src1, const TDivisor* src2, TDivisor* dst);
|
||||||
|
void mul(const TDivisor* src, QWORD mult, TDivisor* dst);
|
||||||
|
void mul128(const TDivisor* src, QWORD mult_lo, QWORD mult_hi, TDivisor* dst);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif //UMSKT_CONFID_H
|
#endif //UMSKT_CONFID_H
|
||||||
|
355
src/libumskt/confid/divisor.cpp
Normal file
355
src/libumskt/confid/divisor.cpp
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
/**
|
||||||
|
* This file is a part of the UMSKT Project
|
||||||
|
*
|
||||||
|
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @FileCreated by Neo on 12/05/2023
|
||||||
|
* @Maintainer Neo
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "confid.h"
|
||||||
|
|
||||||
|
int Divisor::find_divisor_v(TDivisor* d)
|
||||||
|
{
|
||||||
|
// u | v^2 - f
|
||||||
|
// u = u0 + u1*x + x^2
|
||||||
|
// f%u = f0 + f1*x
|
||||||
|
QWORD v1, f2[6];
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
f2[i] = parent->f[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
const QWORD u0 = d->u[0];
|
||||||
|
const QWORD u1 = d->u[1];
|
||||||
|
for (int j = 4; j--; )
|
||||||
|
{
|
||||||
|
f2[j] = parent->residue->sub(f2[j], parent->residue->mul(u0, f2[j + 2]));
|
||||||
|
f2[j + 1] = parent->residue->sub(f2[j + 1], parent->residue->mul(u1, f2[j + 2]));
|
||||||
|
f2[j + 2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// v = v0 + v1*x
|
||||||
|
// u | (v0^2 - f0) + (2*v0*v1 - f1)*x + v1^2*x^2 = u0*v1^2 + u1*v1^2*x + v1^2*x^2
|
||||||
|
// v0^2 - f0 = u0*v1^2
|
||||||
|
// 2*v0*v1 - f1 = u1*v1^2
|
||||||
|
// v0^2 = f0 + u0*v1^2 = (f1 + u1*v1^2)^2 / (2*v1)^2
|
||||||
|
// (f1^2) + 2*(f1*u1-2*f0) * v1^2 + (u1^2-4*u0) * v1^4 = 0
|
||||||
|
// v1^2 = ((2*f0-f1*u1) +- 2*sqrt(-f0*f1*u1 + f0^2 + f1^2*u0))) / (u1^2-4*u0)
|
||||||
|
const QWORD f0 = f2[0];
|
||||||
|
const QWORD f1 = f2[1];
|
||||||
|
const QWORD u0double = parent->residue->add(u0, u0);
|
||||||
|
const QWORD coeff2 = parent->residue->sub(parent->residue->mul(u1, u1), parent->residue->add(u0double, u0double));
|
||||||
|
const QWORD coeff1 = parent->residue->sub(parent->residue->add(f0, f0), parent->residue->mul(f1, u1));
|
||||||
|
|
||||||
|
if (coeff2 == 0)
|
||||||
|
{
|
||||||
|
if (coeff1 == 0)
|
||||||
|
{
|
||||||
|
if (f1 == 0)
|
||||||
|
{
|
||||||
|
// impossible
|
||||||
|
//printf("bad f(), double root detected\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
QWORD sqr = parent->residue->mul(parent->residue->mul(f1, f1), parent->residue->inv(parent->residue->add(coeff1, coeff1)));
|
||||||
|
v1 = parent->residue->sqrt(sqr);
|
||||||
|
if (v1 == BAD)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QWORD d = parent->residue->add(parent->residue->mul(f0, f0), parent->residue->mul(f1, parent->residue->sub(parent->residue->mul(f1, u0), parent->residue->mul(f0, u1))));
|
||||||
|
d = parent->residue->sqrt(d);
|
||||||
|
if (d == BAD)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
d = parent->residue->add(d, d);
|
||||||
|
QWORD inv = parent->residue->inv(coeff2);
|
||||||
|
QWORD root = parent->residue->mul(parent->residue->add(coeff1, d), inv);
|
||||||
|
v1 = parent->residue->sqrt(root);
|
||||||
|
if (v1 == BAD)
|
||||||
|
{
|
||||||
|
root = parent->residue->mul(parent->residue->sub(coeff1, d), inv);
|
||||||
|
v1 = parent->residue->sqrt(root);
|
||||||
|
if (v1 == BAD)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD v0 = parent->residue->mul(parent->residue->add(f1, parent->residue->mul(u1, parent->residue->mul(v1, v1))), parent->residue->inv(parent->residue->add(v1, v1)));
|
||||||
|
d->v[0] = v0;
|
||||||
|
d->v[1] = v1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Divisor::u2poly(const TDivisor* src, QWORD polyu[3], QWORD polyv[2])
|
||||||
|
{
|
||||||
|
if (src->u[1] != BAD)
|
||||||
|
{
|
||||||
|
polyu[0] = src->u[0];
|
||||||
|
polyu[1] = src->u[1];
|
||||||
|
polyu[2] = 1;
|
||||||
|
polyv[0] = src->v[0];
|
||||||
|
polyv[1] = src->v[1];
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->u[0] != BAD)
|
||||||
|
{
|
||||||
|
polyu[0] = src->u[0];
|
||||||
|
polyu[1] = 1;
|
||||||
|
polyv[0] = src->v[0];
|
||||||
|
polyv[1] = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
polyu[0] = 1;
|
||||||
|
polyv[0] = 0;
|
||||||
|
polyv[1] = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Divisor::add(const TDivisor* src1, const TDivisor* src2, TDivisor* dst)
|
||||||
|
{
|
||||||
|
QWORD u1[3], u2[3], v1[2], v2[2];
|
||||||
|
int u1deg = u2poly(src1, u1, v1);
|
||||||
|
int u2deg = u2poly(src2, u2, v2);
|
||||||
|
|
||||||
|
// extended gcd: d1 = gcd(u1, u2) = e1*u1 + e2*u2
|
||||||
|
int d1deg, e1deg, e2deg;
|
||||||
|
QWORD d1[3], e1[3], e2[3];
|
||||||
|
parent->polynomial->xgcd(u1deg, u1, u2deg, u2, &d1deg, d1, &e1deg, e1, &e2deg, e2);
|
||||||
|
assert(e1deg <= 1);
|
||||||
|
assert(e2deg <= 1);
|
||||||
|
|
||||||
|
// extended gcd again: d = gcd(d1, v1+v2) = c1*d1 + c2*(v1+v2)
|
||||||
|
QWORD b[3] = {parent->residue->add(v1[0], v2[0]), parent->residue->add(v1[1], v2[1]), 0};
|
||||||
|
int bdeg = (b[1] == 0 ? (b[0] == 0 ? -1 : 0) : 1);
|
||||||
|
int ddeg, c1deg, c2deg;
|
||||||
|
QWORD d[3], c1[3], c2[3];
|
||||||
|
parent->polynomial->xgcd(d1deg, d1, bdeg, b, &ddeg, d, &c1deg, c1, &c2deg, c2);
|
||||||
|
assert(c1deg <= 0);
|
||||||
|
assert(c2deg <= 1);
|
||||||
|
assert(ddeg >= 0);
|
||||||
|
QWORD dmult = parent->residue->inv(d[ddeg]);
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ddeg; i++)
|
||||||
|
{
|
||||||
|
d[i] = parent->residue->mul(d[i], dmult);
|
||||||
|
}
|
||||||
|
|
||||||
|
d[i] = 1;
|
||||||
|
for (i = 0; i <= c1deg; i++)
|
||||||
|
{
|
||||||
|
c1[i] = parent->residue->mul(c1[i], dmult);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i <= c2deg; i++)
|
||||||
|
{
|
||||||
|
c2[i] = parent->residue->mul(c2[i], dmult);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD u[5];
|
||||||
|
int udeg = parent->polynomial->mul(u1deg, u1, u2deg, u2, -1, u);
|
||||||
|
// u is monic
|
||||||
|
|
||||||
|
QWORD v[7], tmp[7];
|
||||||
|
int vdeg, tmpdeg;
|
||||||
|
// c1*(e1*u1*v2 + e2*u2*v1) + c2*(v1*v2 + f)
|
||||||
|
// c1*(e1*u1*(v2-v1) + d1*v1) + c2*(v1*v2 + f)
|
||||||
|
v[0] = parent->residue->sub(v2[0], v1[0]);
|
||||||
|
v[1] = parent->residue->sub(v2[1], v1[1]);
|
||||||
|
tmpdeg = parent->polynomial->mul(e1deg, e1, 1, v, -1, tmp);
|
||||||
|
vdeg = parent->polynomial->mul(u1deg, u1, tmpdeg, tmp, -1, v);
|
||||||
|
vdeg = parent->polynomial->mul(d1deg, d1, 1, v1, vdeg, v);
|
||||||
|
|
||||||
|
for (i = 0; i <= vdeg; i++)
|
||||||
|
{
|
||||||
|
v[i] = parent->residue->mul(v[i], c1[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tmp, parent->f, 6 * sizeof(parent->f[0]));
|
||||||
|
tmpdeg = 5;
|
||||||
|
tmpdeg = parent->polynomial->mul(1, v1, 1, v2, tmpdeg, tmp);
|
||||||
|
vdeg = parent->polynomial->mul(c2deg, c2, tmpdeg, tmp, vdeg, v);
|
||||||
|
|
||||||
|
if (ddeg > 0)
|
||||||
|
{
|
||||||
|
assert(udeg >= 2*ddeg);
|
||||||
|
QWORD udiv[5];
|
||||||
|
parent->polynomial->div_monic(udeg, u, ddeg, d, udiv); udeg -= ddeg;
|
||||||
|
parent->polynomial->div_monic(udeg, udiv, ddeg, d, u); udeg -= ddeg;
|
||||||
|
if (vdeg >= 0)
|
||||||
|
{
|
||||||
|
assert(vdeg >= ddeg);
|
||||||
|
parent->polynomial->div_monic(vdeg, v, ddeg, d, udiv); vdeg -= ddeg;
|
||||||
|
memcpy(v, udiv, (vdeg + 1) * sizeof(v[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vdeg = parent->polynomial->div_monic(vdeg, v, udeg, u, NULL);
|
||||||
|
|
||||||
|
while (udeg > 2) {
|
||||||
|
assert(udeg <= 4);
|
||||||
|
assert(vdeg <= 3);
|
||||||
|
// u' = monic((f-v^2)/u), v'=-v mod u'
|
||||||
|
tmpdeg = parent->polynomial->mul(vdeg, v, vdeg, v, -1, tmp);
|
||||||
|
for (i = 0; i <= tmpdeg && i <= 5; i++)
|
||||||
|
{
|
||||||
|
tmp[i] = parent->residue->sub(parent->f[i], tmp[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i <= tmpdeg; i++)
|
||||||
|
{
|
||||||
|
tmp[i] = parent->residue->sub(0, tmp[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i <= 5; i++)
|
||||||
|
{
|
||||||
|
tmp[i] = parent->f[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpdeg = i - 1;
|
||||||
|
QWORD udiv[5];
|
||||||
|
parent->polynomial->div_monic(tmpdeg, tmp, udeg, u, udiv);
|
||||||
|
|
||||||
|
udeg = tmpdeg - udeg;
|
||||||
|
QWORD mult = parent->residue->inv(udiv[udeg]);
|
||||||
|
|
||||||
|
for (i = 0; i < udeg; i++)
|
||||||
|
{
|
||||||
|
u[i] = parent->residue->mul(udiv[i], mult);
|
||||||
|
}
|
||||||
|
|
||||||
|
u[i] = 1;
|
||||||
|
|
||||||
|
for (i = 0; i <= vdeg; i++)
|
||||||
|
{
|
||||||
|
v[i] = parent->residue->sub(0, v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
vdeg = parent->polynomial->div_monic(vdeg, v, udeg, u, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (udeg == 2)
|
||||||
|
{
|
||||||
|
dst->u[0] = u[0];
|
||||||
|
dst->u[1] = u[1];
|
||||||
|
dst->v[0] = (vdeg >= 0 ? v[0] : 0);
|
||||||
|
dst->v[1] = (vdeg >= 1 ? v[1] : 0);
|
||||||
|
}
|
||||||
|
else if (udeg == 1)
|
||||||
|
{
|
||||||
|
dst->u[0] = u[0];
|
||||||
|
dst->u[1] = BAD;
|
||||||
|
dst->v[0] = (vdeg >= 0 ? v[0] : 0);
|
||||||
|
dst->v[1] = BAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(udeg == 0);
|
||||||
|
dst->u[0] = BAD;
|
||||||
|
dst->u[1] = BAD;
|
||||||
|
dst->v[0] = BAD;
|
||||||
|
dst->v[1] = BAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define divisor_double(src, dst) add(src, src, dst)
|
||||||
|
|
||||||
|
void Divisor::mul(const TDivisor* src, QWORD mult, TDivisor* dst)
|
||||||
|
{
|
||||||
|
if (mult == 0)
|
||||||
|
{
|
||||||
|
dst->u[0] = BAD;
|
||||||
|
dst->u[1] = BAD;
|
||||||
|
dst->v[0] = BAD;
|
||||||
|
dst->v[1] = BAD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDivisor cur = *src;
|
||||||
|
while (!(mult & 1))
|
||||||
|
{
|
||||||
|
divisor_double(&cur, &cur);
|
||||||
|
mult >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst = cur;
|
||||||
|
while ((mult >>= 1) != 0)
|
||||||
|
{
|
||||||
|
divisor_double(&cur, &cur);
|
||||||
|
if (mult & 1)
|
||||||
|
{
|
||||||
|
add(dst, &cur, dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Divisor::mul128(const TDivisor* src, QWORD mult_lo, QWORD mult_hi, TDivisor* dst)
|
||||||
|
{
|
||||||
|
if (mult_lo == 0 && mult_hi == 0)
|
||||||
|
{
|
||||||
|
dst->u[0] = BAD;
|
||||||
|
dst->u[1] = BAD;
|
||||||
|
dst->v[0] = BAD;
|
||||||
|
dst->v[1] = BAD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDivisor cur = *src;
|
||||||
|
while (!(mult_lo & 1))
|
||||||
|
{
|
||||||
|
divisor_double(&cur, &cur);
|
||||||
|
mult_lo >>= 1;
|
||||||
|
if (mult_hi & 1) {
|
||||||
|
mult_lo |= (1ULL << 63);
|
||||||
|
}
|
||||||
|
mult_hi >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst = cur;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
mult_lo >>= 1;
|
||||||
|
if (mult_hi & 1)
|
||||||
|
{
|
||||||
|
mult_lo |= (1ULL << 63);
|
||||||
|
}
|
||||||
|
|
||||||
|
mult_hi >>= 1;
|
||||||
|
if (mult_lo == 0 && mult_hi == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
divisor_double(&cur, &cur);
|
||||||
|
if (mult_lo & 1)
|
||||||
|
{
|
||||||
|
add(dst, &cur, dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
184
src/libumskt/confid/polynomial.cpp
Normal file
184
src/libumskt/confid/polynomial.cpp
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/**
|
||||||
|
* This file is a part of the UMSKT Project
|
||||||
|
*
|
||||||
|
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @FileCreated by Neo on 12/05/2023
|
||||||
|
* @Maintainer Neo
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "confid.h"
|
||||||
|
|
||||||
|
// generic short slow code
|
||||||
|
int Polynomial::mul(int adeg, const QWORD a[], int bdeg, const QWORD b[], int resultprevdeg, QWORD result[])
|
||||||
|
{
|
||||||
|
if (adeg < 0 || bdeg < 0)
|
||||||
|
{
|
||||||
|
return resultprevdeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = resultprevdeg + 1; i <= adeg + bdeg; i++)
|
||||||
|
{
|
||||||
|
result[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
resultprevdeg = i - 1;
|
||||||
|
|
||||||
|
for (i = 0; i <= adeg; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j <= bdeg; j++)
|
||||||
|
{
|
||||||
|
result[i + j] = parent->residue->add(result[i + j], parent->residue->mul(a[i], b[j]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (resultprevdeg >= 0 && result[resultprevdeg] == 0)
|
||||||
|
{
|
||||||
|
--resultprevdeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultprevdeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Polynomial::div_monic(int adeg, QWORD a[], int bdeg, const QWORD b[], QWORD* quotient)
|
||||||
|
{
|
||||||
|
assert(bdeg >= 0);
|
||||||
|
assert(b[bdeg] == 1);
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = adeg - bdeg; i >= 0; i--)
|
||||||
|
{
|
||||||
|
QWORD q = a[i + bdeg];
|
||||||
|
if (quotient)
|
||||||
|
{
|
||||||
|
quotient[i] = q;
|
||||||
|
}
|
||||||
|
for (j = 0; j < bdeg; j++)
|
||||||
|
{
|
||||||
|
a[i + j] = parent->residue->sub(a[i + j], parent->residue->mul(q, b[j]));
|
||||||
|
}
|
||||||
|
a[i + j] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += bdeg;
|
||||||
|
while (i >= 0 && a[i] == 0)
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Polynomial::xgcd(int adeg, const QWORD a[3], int bdeg, const QWORD b[3], int* pgcddeg, QWORD gcd[3], int* pmult1deg, QWORD mult1[3], int* pmult2deg, QWORD mult2[3])
|
||||||
|
{
|
||||||
|
int sdeg = -1;
|
||||||
|
QWORD s[3] = {0, 0, 0};
|
||||||
|
|
||||||
|
int mult1deg = 0;
|
||||||
|
mult1[0] = 1; mult1[1] = 0; mult1[2] = 0;
|
||||||
|
|
||||||
|
int tdeg = 0;
|
||||||
|
QWORD t[3] = {1, 0, 0};
|
||||||
|
|
||||||
|
int mult2deg = -1;
|
||||||
|
mult2[0] = 0; mult2[1] = 0; mult2[2] = 0;
|
||||||
|
|
||||||
|
int rdeg = bdeg;
|
||||||
|
QWORD r[3] = {b[0], b[1], b[2]};
|
||||||
|
|
||||||
|
int gcddeg = adeg;
|
||||||
|
gcd[0] = a[0]; gcd[1] = a[1]; gcd[2] = a[2];
|
||||||
|
// s*u1 + t*u2 = r
|
||||||
|
// mult1*u1 + mult2*u2 = gcd
|
||||||
|
|
||||||
|
while (rdeg >= 0)
|
||||||
|
{
|
||||||
|
if (rdeg > gcddeg)
|
||||||
|
{
|
||||||
|
unsigned tmp;
|
||||||
|
int tmpi;
|
||||||
|
tmp = rdeg; rdeg = gcddeg; gcddeg = tmp;
|
||||||
|
tmpi = sdeg; sdeg = mult1deg; mult1deg = tmpi;
|
||||||
|
tmpi = tdeg; tdeg = mult2deg; mult2deg = tmpi;
|
||||||
|
QWORD tmp2;
|
||||||
|
tmp2 = r[0]; r[0] = gcd[0]; gcd[0] = tmp2;
|
||||||
|
tmp2 = r[1]; r[1] = gcd[1]; gcd[1] = tmp2;
|
||||||
|
tmp2 = r[2]; r[2] = gcd[2]; gcd[2] = tmp2;
|
||||||
|
tmp2 = s[0]; s[0] = mult1[0]; mult1[0] = tmp2;
|
||||||
|
tmp2 = s[1]; s[1] = mult1[1]; mult1[1] = tmp2;
|
||||||
|
tmp2 = s[2]; s[2] = mult1[2]; mult1[2] = tmp2;
|
||||||
|
tmp2 = t[0]; t[0] = mult2[0]; mult2[0] = tmp2;
|
||||||
|
tmp2 = t[1]; t[1] = mult2[1]; mult2[1] = tmp2;
|
||||||
|
tmp2 = t[2]; t[2] = mult2[2]; mult2[2] = tmp2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int delta = gcddeg - rdeg;
|
||||||
|
QWORD mult = parent->residue->mul(gcd[gcddeg], parent->residue->inv(r[rdeg]));
|
||||||
|
// quotient = mult * x**delta
|
||||||
|
|
||||||
|
assert(rdeg + delta < 3);
|
||||||
|
for (int i = 0; i <= rdeg; i++)
|
||||||
|
{
|
||||||
|
gcd[i + delta] = parent->residue->sub(gcd[i + delta], parent->residue->mul(mult, r[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (gcddeg >= 0 && gcd[gcddeg] == 0)
|
||||||
|
{
|
||||||
|
gcddeg--;
|
||||||
|
}
|
||||||
|
assert(sdeg + delta < 3);
|
||||||
|
|
||||||
|
for (int i = 0; i <= sdeg; i++)
|
||||||
|
{
|
||||||
|
mult1[i + delta] = parent->residue->sub(mult1[i + delta], parent->residue->mul(mult, s[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mult1deg < sdeg + delta)
|
||||||
|
{
|
||||||
|
mult1deg = sdeg + delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mult1deg >= 0 && mult1[mult1deg] == 0)
|
||||||
|
{
|
||||||
|
mult1deg--;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(tdeg + delta < 3);
|
||||||
|
|
||||||
|
for (int i = 0; i <= tdeg; i++)
|
||||||
|
{
|
||||||
|
mult2[i + delta] = parent->residue->sub(mult2[i + delta], parent->residue->mul(mult, t[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mult2deg < tdeg + delta)
|
||||||
|
{
|
||||||
|
mult2deg = tdeg + delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mult2deg >= 0 && mult2[mult2deg] == 0)
|
||||||
|
{
|
||||||
|
mult2deg--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// d1 = gcd, e1 = mult1, e2 = mult2
|
||||||
|
*pgcddeg = gcddeg;
|
||||||
|
*pmult1deg = mult1deg;
|
||||||
|
*pmult2deg = mult2deg;
|
||||||
|
}
|
222
src/libumskt/confid/residue.cpp
Normal file
222
src/libumskt/confid/residue.cpp
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/**
|
||||||
|
* This file is a part of the UMSKT Project
|
||||||
|
*
|
||||||
|
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @FileCreated by Neo on 12/05/2023
|
||||||
|
* @Maintainer Neo
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "confid.h"
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(_M_AMD64) || defined(__aarch64__) || (defined(__arm64__) && defined(__APPLE__))
|
||||||
|
#ifdef __GNUC__
|
||||||
|
inline QWORD Residue::__umul128(QWORD a, QWORD b, QWORD* hi)
|
||||||
|
{
|
||||||
|
OWORD r = (OWORD)a * (OWORD)b;
|
||||||
|
*hi = r >> 64;
|
||||||
|
return (QWORD) r;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define __umul128 _umul128
|
||||||
|
#endif
|
||||||
|
#elif defined(__i386__) || defined(_M_IX86) || defined(__arm__) || defined(__EMSCRIPTEN__)
|
||||||
|
inline QWORD Residue::__umul128(QWORD multiplier, QWORD multiplicand, QWORD *product_hi)
|
||||||
|
{
|
||||||
|
// multiplier = ab = a * 2^32 + b
|
||||||
|
// multiplicand = cd = c * 2^32 + d
|
||||||
|
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
|
||||||
|
QWORD a = multiplier >> 32;
|
||||||
|
QWORD b = multiplier & 0xFFFFFFFF;
|
||||||
|
QWORD c = multiplicand >> 32;
|
||||||
|
QWORD d = multiplicand & 0xFFFFFFFF;
|
||||||
|
|
||||||
|
//QWORD ac = a * c;
|
||||||
|
QWORD ad = a * d;
|
||||||
|
//QWORD bc = b * c;
|
||||||
|
QWORD bd = b * d;
|
||||||
|
|
||||||
|
QWORD adbc = ad + (b * c);
|
||||||
|
QWORD adbc_carry = adbc < ad ? 1 : 0;
|
||||||
|
|
||||||
|
// multiplier * multiplicand = product_hi * 2^64 + product_lo
|
||||||
|
QWORD product_lo = bd + (adbc << 32);
|
||||||
|
QWORD product_lo_carry = product_lo < bd ? 1 : 0;
|
||||||
|
*product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
|
||||||
|
|
||||||
|
return product_lo;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error Unknown architecture detected - please edit confid.cpp to tailor __umul128() your architecture
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QWORD Residue::ui128_quotient_mod(QWORD lo, QWORD hi)
|
||||||
|
{
|
||||||
|
// hi:lo * ceil(2**170/MOD) >> (64 + 64 + 42)
|
||||||
|
QWORD prod1;
|
||||||
|
__umul128(lo, parent->p0, &prod1);
|
||||||
|
|
||||||
|
QWORD part1hi, part1lo;
|
||||||
|
part1lo = __umul128(lo, parent->p1, &part1hi);
|
||||||
|
|
||||||
|
QWORD part2hi, part2lo;
|
||||||
|
part2lo = __umul128(hi, parent->p2, &part2hi);
|
||||||
|
|
||||||
|
QWORD sum1 = part1lo + part2lo;
|
||||||
|
unsigned sum1carry = (sum1 < part1lo);
|
||||||
|
sum1 += prod1;
|
||||||
|
sum1carry += (sum1 < prod1);
|
||||||
|
QWORD prod2 = part1hi + part2hi + sum1carry;
|
||||||
|
|
||||||
|
QWORD prod3hi, prod3lo;
|
||||||
|
prod3lo = __umul128(hi, parent->p3, &prod3hi);
|
||||||
|
|
||||||
|
prod3lo += prod2;
|
||||||
|
prod3hi += (prod3lo < prod2);
|
||||||
|
return (prod3lo >> 42) | (prod3hi << 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD Residue::mul(QWORD x, QWORD y)
|
||||||
|
{
|
||||||
|
// * ceil(2**170/MOD) = 0x2d351 c6d04f8b|604fa6a1 c6346a87 for (p-1)*(p-1) max
|
||||||
|
QWORD hi;
|
||||||
|
QWORD lo = __umul128(x, y, &hi);
|
||||||
|
QWORD quotient = ui128_quotient_mod(lo, hi);
|
||||||
|
return lo - quotient * parent->MOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD Residue::pow(QWORD x, QWORD y)
|
||||||
|
{
|
||||||
|
if (y == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD cur = x;
|
||||||
|
while (!(y & 1))
|
||||||
|
{
|
||||||
|
cur = mul(cur, cur);
|
||||||
|
y >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD res = cur;
|
||||||
|
while ((y >>= 1) != 0)
|
||||||
|
{
|
||||||
|
cur = mul(cur, cur);
|
||||||
|
if (y & 1)
|
||||||
|
{
|
||||||
|
res = mul(res, cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD Residue::add(QWORD x, QWORD y)
|
||||||
|
{
|
||||||
|
QWORD z = x + y;
|
||||||
|
//z = z - (z >= MOD ? MOD : 0);
|
||||||
|
if (z >= parent->MOD)
|
||||||
|
{
|
||||||
|
z -= parent->MOD;
|
||||||
|
}
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD Residue::sub(QWORD x, QWORD y)
|
||||||
|
{
|
||||||
|
QWORD z = x - y;
|
||||||
|
//z += (x < y ? MOD : 0);
|
||||||
|
if (x < y)
|
||||||
|
{
|
||||||
|
z += parent->MOD;
|
||||||
|
}
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD Residue::inverse(QWORD u, QWORD v)
|
||||||
|
{
|
||||||
|
//assert(u);
|
||||||
|
int64_t tmp;
|
||||||
|
int64_t xu = 1, xv = 0;
|
||||||
|
QWORD v0 = v;
|
||||||
|
while (u > 1)
|
||||||
|
{
|
||||||
|
QWORD d = v / u; QWORD remainder = v % u;
|
||||||
|
tmp = u; u = remainder; v = tmp;
|
||||||
|
tmp = xu; xu = xv - d * xu; xv = tmp;
|
||||||
|
}
|
||||||
|
xu += (xu < 0 ? v0 : 0);
|
||||||
|
return xu;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD Residue::inv(QWORD x)
|
||||||
|
{
|
||||||
|
return inverse(x, parent->MOD);
|
||||||
|
// return residue_pow(x, MOD - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD Residue::sqrt(QWORD what)
|
||||||
|
{
|
||||||
|
if (!what)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWORD g = parent->NON_RESIDUE, z, y, r, x, b, t;
|
||||||
|
QWORD e = 0, q = parent->MOD - 1;
|
||||||
|
|
||||||
|
while (!(q & 1))
|
||||||
|
{
|
||||||
|
e++, q >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
z = pow(g, q);
|
||||||
|
y = z;
|
||||||
|
r = e;
|
||||||
|
x = pow(what, (q - 1) / 2);
|
||||||
|
b = mul(mul(what, x), x);
|
||||||
|
x = mul(what, x);
|
||||||
|
while (b != 1) {
|
||||||
|
QWORD m = 0, b2 = b;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
m++;
|
||||||
|
b2 = mul(b2, b2);
|
||||||
|
}
|
||||||
|
while (b2 != 1);
|
||||||
|
|
||||||
|
if (m == r)
|
||||||
|
{
|
||||||
|
return BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = pow(y, 1 << (r - m - 1));
|
||||||
|
y = mul(t, t);
|
||||||
|
r = m;
|
||||||
|
x = mul(x, t);
|
||||||
|
b = mul(b, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mul(x, x) != what)
|
||||||
|
{
|
||||||
|
//printf("internal error in sqrt\n");
|
||||||
|
return BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user