├── config.py
├── examples
└── G4_MariaDB_test
│ ├── Main.tscn
│ ├── project.godot
│ ├── icon.svg.import
│ ├── main.gd
│ ├── icon.svg
│ └── create_db.sql.txt
├── SCsub
├── LICENSE.md
├── register_types.h
├── README.md
├── ed25519_ref10
├── ed25519_sc.h
├── ed25519_auth.h
├── ed25519_fe.h
├── ed25519_sign.cpp
├── ed25519_ge.h
├── ed25519_auth.cpp
├── ed25519_ge.cpp
├── ed25519_sc.cpp
└── ed25519_fe.cpp
├── register_types.cpp
├── mariadb_auth.h
├── mariadb_auth.cpp
├── mariadb_conversions.h
├── .gitignore
├── mariadb.h
└── mariadb.cpp
/config.py:
--------------------------------------------------------------------------------
1 | def can_build(env, platform):
2 | return True
3 |
4 | def configure(env):
5 | pass
6 |
--------------------------------------------------------------------------------
/examples/G4_MariaDB_test/Main.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://bnx22kqnnvyxf"]
2 |
3 | [ext_resource type="Script" path="res://main.gd" id="1_gmex7"]
4 |
5 | [node name="Main" type="Node2D"]
6 | script = ExtResource("1_gmex7")
7 |
8 | [node name="Timer" type="Timer" parent="."]
9 | unique_name_in_owner = true
10 | wait_time = 0.1
11 |
12 | [connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]
13 |
--------------------------------------------------------------------------------
/SCsub:
--------------------------------------------------------------------------------
1 | Import('env')
2 | Import("env_modules")
3 |
4 | env.Append(CPPPATH=["#thirdparty/mbedtls/include/", "ed25519_ref10/"])
5 |
6 |
7 | # Make includes relative to the folder path specified here so our includes are clean
8 | env.Prepend(CPPPATH=["#modules/mariadb/"])
9 |
10 | env.add_source_files(env.modules_sources, "*.cpp") # Add all cpp files to the build
11 | env.add_source_files(env.modules_sources, "ed25519_ref10/*.cpp") # Add all cpp files to the build
12 |
--------------------------------------------------------------------------------
/examples/G4_MariaDB_test/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="G4_MariaDB_test"
14 | run/main_scene="res://Main.tscn"
15 | config/features=PackedStringArray("4.2")
16 | config/icon="res://icon.svg"
17 |
18 | [filesystem]
19 |
20 | import/blender/enabled=false
21 | import/fbx/enabled=false
22 |
--------------------------------------------------------------------------------
/examples/G4_MariaDB_test/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bedkr75tqprf3"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/lossy_quality=0.7
20 | compress/hdr_compression=1
21 | compress/bptc_ldr=0
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Shawn Shipton
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/register_types.h:
--------------------------------------------------------------------------------
1 | void register_mariadb_types();
2 | void unregister_mariadb_types();
3 |
4 | /*************************************************************************/
5 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
6 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
7 | /* */
8 | /* Permission is hereby granted, free of charge, to any person obtaining */
9 | /* a copy of this software and associated documentation files (the */
10 | /* "Software"), to deal in the Software without restriction, including */
11 | /* without limitation the rights to use, copy, modify, merge, publish, */
12 | /* distribute, sublicense, and/or sell copies of the Software, and to */
13 | /* permit persons to whom the Software is furnished to do so, subject to */
14 | /* the following conditions: */
15 | /* */
16 | /* The above copyright notice and this permission notice shall be */
17 | /* included in all copies or substantial portions of the Software. */
18 | /* */
19 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
20 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
21 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
22 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
23 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
24 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
25 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
26 | /*************************************************************************/
27 |
28 | #ifndef MARIADB_REGISTER_TYPES_H
29 | #define MARIADB_REGISTER_TYPES_H
30 |
31 | #include "modules/register_module_types.h"
32 |
33 | void initialize_mariadb_module(ModuleInitializationLevel p_level);
34 | void uninitialize_mariadb_module(ModuleInitializationLevel p_level);
35 |
36 | #endif // MARIADB_REGISTER_TYPES_H
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
Announcement
2 |
7 | Now available on the Godot AssetLib version 4.3+
8 | # godot-mariadb
9 | A Godot engine module for MariaDB that is a MIT licensed connector separate from the Maria/MySQL GPL connectors.
10 | This module will compile on Linux, Windows, probably Mac. However, it is extremely suggested that you use this on Linux, there have been reports of unconfirmed Windows issues.
11 |
12 | Originally created for Godot 3.4 and currently works on 3.5.3 and 4.1.3, the main branch will stay current with Godot stable releases for Godot 3.x checkout the relevant release or branch.
13 |
14 | **To compile on to a stable version you will need to clone the Godot repo...**
15 | git clone https://github.com/godotengine/godot.git
16 |
17 | **List the stable releases with...**
18 | git tag
19 | **-or- find a major release with, eg 4.x-stable**
20 | git tag -l '4.\*stable'
21 |
22 | **Checkout the stable release you want, in this case 4.0.3-stable...**
23 | git checkout 4.0.3-stable
24 |
25 | **Change to the modules directory...**
26 | cd modules
27 |
28 | **Clone this repo as a git submodule...**
29 | git submodule add https://github.com/sigrudds1/godot-mariadb.git mariadb
30 |
31 | **Change to the just created mariadb directory...**
32 | cd mariadb
33 |
34 | **Find the relevant release to the Godot version...**
35 | git tag
36 |
37 | **Checkout/switch to the relevant release, e.g. match Godot 4.0.4-stable, git version 2.23+**
38 | git checkout v4.0.3
39 |
40 | **Alternately you can use a branch rather than release...**
41 | git branch -v -a
42 |
43 | **Checkout the branch, e.g. 4.x, git version 2.23+**
44 | git checkout 4.x
45 |
46 | **Change back to the main Godot directory...**
47 | cd ../..
48 |
49 | **Compile Godot, e.g. editor version Linux 64 bit, see the Godot manual for compilation instructions for other releases and export templates, make sure you're on the correct manual version.**
50 | Godot 4.x
51 | scons -j$(nproc) platform=linuxbsd target=editor arch=x86_64
52 | Godot 3.x
53 | scons -j$(nproc) platform=x11
54 |
55 | [Buy Me A Coffee](https://buymeacoffee.com/VikingTinkerer)
56 | or
57 | [Buy Me A Ko-Fi](https://ko-fi.com/vikingtinkerer)
58 |
59 |
--------------------------------------------------------------------------------
/ed25519_ref10/ed25519_sc.h:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* ed25519_sc.h */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | /* This file was derived from information found at */
32 | /* https://tools.ietf.org/html/rfc8032#page-44 */
33 |
34 | #ifndef ED25519_SC_H
35 | #define ED25519_SC_H
36 |
37 | #include
38 |
39 | void sc_reduce(uint8_t *s);
40 | void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, const uint8_t *c);
41 |
42 | #endif // !ED25519_SC_H
43 |
--------------------------------------------------------------------------------
/register_types.cpp:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* register_types.cpp */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | #include "register_types.h"
32 | #include "mariadb.h"
33 |
34 |
35 | void initialize_mariadb_module(ModuleInitializationLevel p_level) {
36 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
37 | return;
38 | }
39 | GDREGISTER_CLASS(MariaDB);
40 | }
41 |
42 | void uninitialize_mariadb_module(ModuleInitializationLevel p_level) {
43 | if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
44 | return;
45 | }
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/mariadb_auth.h:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* mariadb_auth.h */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | #ifndef MARIADB_AUTH_H
32 | #define MARIADB_AUTH_H
33 |
34 | #include "core/templates/vector.h"
35 |
36 | Vector get_caching_sha2_passwd_hash(Vector p_sha256_hashed_passwd, Vector p_srvr_salt);
37 |
38 | Vector get_client_ed25519_signature(Vector p_sha512_hashed_passwd, Vector p_svr_msg);
39 |
40 | Vector get_mysql_native_password_hash(Vector p_sha1_hashed_passwd, Vector p_srvr_salt);
41 |
42 | #endif // !MARIADB_AUTH_H
43 |
--------------------------------------------------------------------------------
/examples/G4_MariaDB_test/main.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 |
3 | # See the create_db.sql file to insall the data needed for this test
4 | # Run the insert record functions once, then comment it out.
5 |
6 | var ed:Dictionary = {
7 | "db_plain_text_pwd": "secret",
8 | "db_sha512_hashed_pwd": "bd2b1aaf7ef4f09be9f52ce2d8d599674d81aa9d6a4421696dc4d93dd0619d682ce56b4d64a9ef097761ced99e0f67265b5f76085e5b0ee7ca4696b2ad6fe2b2",
9 | "db_hostname": "127.0.0.1",
10 | "db_max_conns": 5,
11 | "db_name": "Godot_Test",
12 | "db_port": 3306,
13 | "db_user": "godot_user"
14 | }
15 |
16 | var qry_stmt_array: PackedStringArray = [
17 | "SELECT * FROM Godot_Test.many_records;",
18 | "SELECT * FROM Godot_Test.many_columns;"
19 | ]
20 |
21 | var query_tmr: float = 0
22 | var itr: int = 0
23 | var db: MariaDB
24 |
25 | func _ready() -> void:
26 | db = MariaDB.new()
27 | _connect_to_db_srvr()
28 | # _insert_many_columns()
29 | # _insert_many_records()
30 | %Timer.start()
31 | # _run_db()
32 |
33 | func _exit_tree() -> void:
34 | db.disconnect_db()
35 |
36 |
37 | func print_db_response(pba: PackedByteArray) -> void:
38 | for idx in range(pba.size() - 1, -1, -1):
39 | if pba[idx] < 32:
40 | pba.remove_at(idx)
41 | print(pba.get_string_from_ascii())
42 |
43 |
44 | func _run_db() -> void:
45 | if !db.is_connected_db():
46 | _connect_to_db_srvr()
47 | else:
48 | var start_uticks := Time.get_ticks_usec()
49 | var stmt: String = qry_stmt_array[itr % qry_stmt_array.size()]
50 | # var stmt: String = qry_stmt_array[0]
51 | # print(stmt)
52 | var qry = db.query(stmt)
53 | if typeof(qry) == TYPE_ARRAY:
54 | var end_uticks := Time.get_ticks_usec()
55 | print("total records received:", qry.size(), " time:", Time.get_ticks_usec() - start_uticks, " usecs itr:", itr)
56 | else:
57 | %Timer.stop()
58 | print(stmt)
59 | print("itr:", itr, " - ERROR:", qry)
60 |
61 | itr += 1
62 |
63 |
64 | func _connect_to_db_srvr() -> void:
65 | var err = db.connect_db(
66 | ed["db_hostname"],
67 | ed["db_port"],
68 | ed["db_name"],
69 | ed["db_user"],
70 | ed["db_sha512_hashed_pwd"],
71 | MariaDB.AUTH_TYPE_ED25519,
72 | true
73 | );
74 | if err:
75 | print("db connect err:", err)
76 |
77 |
78 | func _insert_many_columns() -> void:
79 | var stmt: String = "INSERT INTO Godot_Test.many_columns VALUES "
80 | for i in range(1, 253):
81 | stmt += "(%d)" % i
82 |
83 | stmt += ";"
84 | print(stmt)
85 | var err = db.query(stmt)
86 | if err != OK:
87 | printerr("Insert fail:" , err)
88 |
89 |
90 | func _insert_many_records() -> void:
91 | var stmt: String = "INSERT INTO Godot_Test.`many_records (type, zone_id, player_id, map_id, " +\
92 | "text_field) VALUES "
93 | for i in 10:
94 | stmt += "(%d, %d, %d, %d, %s)" % [i * 10 + 1, i * 10 + 2, i * 10 + 3, i * 10 + 4, "Some text for record %d" % i]
95 |
96 | stmt += ";"
97 | print(stmt)
98 | var err = db.query(stmt)
99 | if err != OK:
100 | printerr("Insert fail:" , err)
101 |
102 |
103 | func _on_timer_timeout() -> void:
104 | _run_db()
105 |
--------------------------------------------------------------------------------
/ed25519_ref10/ed25519_auth.h:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* ed25519_auth.h */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | /* This file was derived from information found at */
32 | /* https://tools.ietf.org/html/rfc8032#page-44 */
33 | /* REF https://security.stackexchange.com/questions/218046/how-does-mariadbs-ed25519-auth-scheme-work */
34 |
35 | #ifndef ED25519_AUTH_H
36 | #define ED25519_AUTH_H
37 |
38 | #include
39 | #include
40 |
41 | void ed25519_sign_msg(const uint8_t *pwd_sha512_src, const uint8_t *message_src, size_t message_len, uint8_t *signature_dst);
42 | void ed25519_create_keypair(const uint8_t *pwd_sha512_src, uint8_t *private_key_dst, uint8_t *public_key_dst);
43 | void ed25519_sign(const uint8_t *message_src, size_t message_len, const uint8_t *public_key_src, const uint8_t *private_key_src, uint8_t *signature_dst);
44 |
45 |
46 | #endif // !ED25519_AUTH_H
47 |
--------------------------------------------------------------------------------
/ed25519_ref10/ed25519_fe.h:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* ed25519_fe.h */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | /* This file was derived from information found at */
32 | /* https://tools.ietf.org/html/rfc8032 */
33 |
34 | //REF https://tools.ietf.org/html/rfc8032#page-13
35 |
36 | #ifndef ED25519_FE_H
37 | #define ED25519_FE_H
38 |
39 | #include
40 |
41 | typedef int32_t fe[10];
42 |
43 | void fe_0(fe h);
44 | void fe_1(fe h);
45 |
46 | void fe_frombytes(fe h, const uint8_t *s);
47 | void fe_tobytes(uint8_t *s, const fe h);
48 |
49 | void fe_copy(fe h, const fe f);
50 | int fe_isnegative(const fe f);
51 | int fe_isnonzero(const fe f);
52 | void fe_cmov(fe f, const fe g, unsigned int b);
53 | void fe_cswap(fe f, fe g, unsigned int b);
54 |
55 | void fe_neg(fe h, const fe f);
56 | void fe_add(fe h, const fe f, const fe g);
57 | void fe_invert(fe out, const fe z);
58 | void fe_sq(fe h, const fe f);
59 | void fe_sq2(fe h, const fe f);
60 | void fe_mul(fe h, const fe f, const fe g);
61 | void fe_mul121666(fe h, fe f);
62 | void fe_pow22523(fe out, const fe z);
63 | void fe_sub(fe h, const fe f, const fe g);
64 |
65 | #endif // !ED25519_FE_H
66 |
--------------------------------------------------------------------------------
/mariadb_auth.cpp:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* mariadb_auth.cpp */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | #include "mariadb_auth.h"
32 | #include "ed25519_ref10/ed25519_auth.h"
33 | #include
34 |
35 |
36 | Vector get_client_ed25519_signature(const Vector p_sha512_hashed_passwd, const Vector p_svr_msg) {
37 | //MySQL does not supprt this auth method
38 | Vector rtn_val;
39 | rtn_val.resize(64);
40 | ed25519_sign_msg(p_sha512_hashed_passwd.ptr(), p_svr_msg.ptr(), 32, rtn_val.ptrw());
41 | return rtn_val;
42 | }
43 |
44 | Vector get_mysql_native_password_hash(Vector p_sha1_hashed_passwd, Vector p_srvr_salt) {
45 | //per https://mariadb.com/kb/en/connection/#mysql_native_password-plugin
46 | //Both MariaDB and MySQL support this auth method
47 | uint8_t hash[20] = {};
48 | CryptoCore::sha1(p_sha1_hashed_passwd.ptr(), 20, hash);
49 | uint8_t combined_salt_pwd[40] = {};
50 | for (size_t i = 0; i < 20; i++) {
51 | combined_salt_pwd[i] = p_srvr_salt[i];
52 | combined_salt_pwd[i + 20] = hash[i];
53 | }
54 |
55 | CryptoCore::sha1((const uint8_t *)combined_salt_pwd, 40, hash);
56 | Vector hash_out;
57 | for (size_t i = 0; i < 20; i++) {
58 | hash_out.push_back(p_sha1_hashed_passwd[i] ^ hash[i]);
59 | }
60 |
61 | return hash_out;
62 | }
63 |
--------------------------------------------------------------------------------
/ed25519_ref10/ed25519_sign.cpp:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* ed25519_sign.cpp */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | /* This file was derived from information found at */
32 | /* https://tools.ietf.org/html/rfc8032#page-44 */
33 |
34 | #include "ed25519_auth.h"
35 | #include "ed25519_ge.h"
36 | #include "ed25519_sc.h"
37 |
38 | #include
39 | #include
40 |
41 | void ed25519_sign(const uint8_t *message_src, size_t message_len, const uint8_t *public_key_src, const uint8_t *private_key_src, uint8_t *signature_dst) {
42 | //message_len should be 32 coming from server
43 |
44 | void *ctx = memalloc(sizeof(mbedtls_sha512_context));
45 | uint8_t sha512[64];
46 | uint8_t hram[64];
47 | ge_p3 R;
48 |
49 | mbedtls_sha512_starts_ret((mbedtls_sha512_context *)ctx, 0);
50 | mbedtls_sha512_update_ret((mbedtls_sha512_context *)ctx, private_key_src + 32, 32);
51 | mbedtls_sha512_update_ret((mbedtls_sha512_context *)ctx, message_src, message_len);
52 | mbedtls_sha512_finish_ret((mbedtls_sha512_context *)ctx, sha512);
53 | mbedtls_sha512_free((mbedtls_sha512_context *)ctx);
54 |
55 | sc_reduce(sha512);
56 | ge_scalarmult_base(&R, sha512);
57 | ge_p3_tobytes(signature_dst, &R);
58 |
59 | mbedtls_sha512_starts_ret((mbedtls_sha512_context *)ctx, 0);
60 | mbedtls_sha512_update_ret((mbedtls_sha512_context *)ctx, signature_dst, 32);
61 | mbedtls_sha512_update_ret((mbedtls_sha512_context *)ctx, public_key_src, 32);
62 | mbedtls_sha512_update_ret((mbedtls_sha512_context *)ctx, message_src, message_len);
63 | mbedtls_sha512_finish_ret((mbedtls_sha512_context *)ctx, hram);
64 | mbedtls_sha512_free((mbedtls_sha512_context *)ctx);
65 |
66 | sc_reduce(hram);
67 | sc_muladd(signature_dst + 32, hram, private_key_src, sha512);
68 |
69 | memfree((mbedtls_sha512_context *)ctx);
70 | }
71 |
--------------------------------------------------------------------------------
/examples/G4_MariaDB_test/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ed25519_ref10/ed25519_ge.h:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* ed25519_ge.h */
3 | /*************************************************************************/
4 | /* This file is part of the */
5 | /* Maria and Mysql database connection module */
6 | /* for use in the Godot Engine */
7 | /* GODOT ENGINE */
8 | /* https://godotengine.org */
9 | /* This file was derived from information found at */
10 | /* https://tools.ietf.org/html/rfc8032#page-44 */
11 | /*************************************************************************/
12 | /* Copyright (c) 2021 Shawn Shipton. https://vikingtinkerer.com */
13 | /* */
14 | /* Permission is hereby granted, free of charge, to any person obtaining */
15 | /* a copy of this software and associated documentation files (the */
16 | /* "Software"), to deal in the Software without restriction, including */
17 | /* without limitation the rights to use, copy, modify, merge, publish, */
18 | /* distribute, sublicense, and/or sell copies of the Software, and to */
19 | /* permit persons to whom the Software is furnished to do so, subject to */
20 | /* the following conditions: */
21 | /* */
22 | /* The above copyright notice and this permission notice shall be */
23 | /* included in all copies or substantial portions of the Software. */
24 | /* */
25 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
26 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
27 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
28 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
29 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
30 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
31 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
32 | /*************************************************************************/
33 |
34 | #ifndef ED25519_GE_H
35 | #define ED25519_GE_H
36 |
37 | #include "ed25519_fe.h"
38 |
39 | /*
40 | ge means group element.
41 |
42 | Here the group is the set of pairs (x,y) of field elements (see fe.h)
43 | satisfying -x^2 + y^2 = 1 + d x^2y^2
44 | where d = -121665/121666.
45 |
46 | Representations:
47 | ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
48 | ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
49 | ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
50 | ge_precomp (Duif): (y+x,y-x,2dxy)
51 | */
52 |
53 | typedef struct {
54 | fe X;
55 | fe Y;
56 | fe Z;
57 | } ge_p2;
58 |
59 | typedef struct {
60 | fe X;
61 | fe Y;
62 | fe Z;
63 | fe T;
64 | } ge_p3;
65 |
66 | typedef struct {
67 | fe X;
68 | fe Y;
69 | fe Z;
70 | fe T;
71 | } ge_p1p1;
72 |
73 | typedef struct {
74 | fe yplusx;
75 | fe yminusx;
76 | fe xy2d;
77 | } ge_precomp;
78 |
79 | typedef struct {
80 | fe YplusX;
81 | fe YminusX;
82 | fe Z;
83 | fe T2d;
84 | } ge_cached;
85 |
86 | void ge_p3_tobytes(uint8_t *s, const ge_p3 *h);
87 | void ge_tobytes(uint8_t *s, const ge_p2 *h);
88 | int ge_frombytes_negate_vartime(ge_p3 *h, const uint8_t *s);
89 |
90 | void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
91 | void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q);
92 | void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a, const ge_p3 *A, const uint8_t *b);
93 | void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q);
94 | void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q);
95 | void ge_scalarmult_base(ge_p3 *h, const uint8_t *a);
96 |
97 | void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p);
98 | void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p);
99 | void ge_p2_0(ge_p2 *h);
100 | void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p);
101 | void ge_p3_0(ge_p3 *h);
102 | void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p);
103 | void ge_p3_to_cached(ge_cached *r, const ge_p3 *p);
104 | void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p);
105 |
106 | #endif // !ED25519_GE_H
107 |
--------------------------------------------------------------------------------
/mariadb_conversions.h:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* mariadb_conversions.h */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | #ifndef MARIADB_CONVERSIONS_H
32 | #define MARIADB_CONVERSIONS_H
33 |
34 | #include
35 | #include
36 | #include
37 |
38 | namespace {
39 |
40 | template
41 | inline T bytes_to_num_itr_pos(const uint8_t *src, const size_t byte_count, size_t &start_pos) {
42 | size_t count = byte_count;
43 |
44 | if (sizeof(T) < byte_count)
45 | count = sizeof(T);
46 |
47 | T result = 0;
48 | for (size_t i = 0; i < count; ++i)
49 | result |= static_cast(src[++start_pos]) << (i * 8);
50 | return result;
51 | }
52 |
53 | inline Vector hex_str_to_v_bytes(const String &hex_str) {
54 | Vector bytes;
55 | for (size_t i = 0; i < (size_t)hex_str.length(); i += 2) {
56 | String byteString = hex_str.substr(i, 2);
57 | uint8_t byte = (uint8_t)strtol(byteString.utf8().ptr(), NULL, 16);
58 | bytes.push_back(byte);
59 | }
60 |
61 | return bytes;
62 | }
63 |
64 | template
65 | inline Vector little_endian_to_vbytes(const T p_value, const size_t p_max_bytes = 0,
66 | const size_t p_start_idx = 0) {
67 | //little endian bytes
68 | size_t count = sizeof(T);
69 | if (p_max_bytes > 0 && p_max_bytes <= count)
70 | count = p_max_bytes;
71 |
72 | Vector vec;
73 | for (size_t i = 0 + p_start_idx; i < count + p_start_idx; i++) {
74 | vec.push_back((uint8_t)(p_value >> (i * 8)) & 0xff);
75 | }
76 |
77 | return vec;
78 | }
79 |
80 | // For testing
81 | // String vbytes_to_int_str(const PackedByteArray p_bytes, String p_delimiter = ",",
82 | // int p_out_len = 0, int p_start_idx = 0){
83 | // int count = p_bytes.size();
84 | // if (p_out_len > count) return "";
85 |
86 | // if (p_out_len > 0) count = p_out_len + p_start_idx;
87 | // String out;
88 | // for (int idx = 0 + p_start_idx; idx < count; ++idx) out += itos(p_bytes[idx]) + p_delimiter;
89 |
90 | // return out;
91 | // }
92 |
93 |
94 | // TODO DO we need other character sets?
95 | // String vbytes_to_ascii_itr_at(const Vector &p_src_buf, size_t &p_last_pos, size_t p_byte_cnt) {
96 | // String rtn;
97 | // for (size_t itr = 0; itr < p_byte_cnt; ++itr)
98 | // rtn += p_src_buf[++p_last_pos];
99 |
100 | // return rtn;
101 | // }
102 |
103 | // Thanks @gladman for testing and suggestion
104 | /**
105 | * \brief This method returns a string from packets using length encoding.
106 | *
107 | * \param src_buf const Vector packet buffer.
108 | * \param last_pos size_t packet buffer position iterator of the last position used,
109 | * this will be incremented by byte count.
110 | * \param byte_cnt size_t byte count to be copied from the packet buffer.
111 | * \return String.
112 | */
113 | String vbytes_to_utf8_itr_at(const Vector &p_src_buf, size_t &p_last_pos, const size_t p_byte_cnt) {
114 | if (p_byte_cnt <= 0 || p_last_pos + p_byte_cnt > (size_t)p_src_buf.size()){
115 | return "";
116 | }
117 |
118 | String rtn_val;
119 | rtn_val.parse_utf8((const char *)p_src_buf.ptr() + p_last_pos + 1, p_byte_cnt);
120 | p_last_pos += p_byte_cnt;
121 | return rtn_val;
122 | }
123 |
124 | } //namespace
125 | #endif // !MARIADB_CONVERSIONS_H
126 |
--------------------------------------------------------------------------------
/ed25519_ref10/ed25519_auth.cpp:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* ed25519_auth.cpp */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | /* This file was derived from information found at */
32 | /* https://tools.ietf.org/html/rfc8032 */
33 |
34 | #include "ed25519_auth.h"
35 | #include "ed25519_ge.h"
36 |
37 | #include
38 |
39 | void ed25519_sign_msg(const uint8_t *pwd_sha512_src, const uint8_t *message_src, size_t message_len, uint8_t *signature_dst) {
40 | uint8_t private_key[64];
41 | uint8_t public_key[64];
42 |
43 | ed25519_create_keypair(pwd_sha512_src, private_key, public_key);
44 | ed25519_sign(message_src, message_len, public_key, private_key, signature_dst);
45 | }
46 |
47 | void ed25519_create_keypair(const uint8_t *pwd_sha512_src, uint8_t *private_key_dst, uint8_t *public_key_dst) {
48 | /*REF RFC 8032 5.1.5 Key Generation https://tools.ietf.org/html/rfc8032#page-13
49 | * The referenced private key that is ran thru sha512 is the password, since we are storing the hashed password
50 | * in the module in case of a needed reconnection, the 1st step in RFC Key Generation will be skipped here.
51 | */
52 |
53 | ge_p3 A;
54 | std::copy(pwd_sha512_src, pwd_sha512_src + 64, private_key_dst);
55 |
56 | /*Step 2 of the RFC
57 | * It references the first and last bits, but that is after pruning,
58 | * I cheated and skipped pruning and reused the variable for the scalar functions.
59 | */
60 | private_key_dst[0] &= 248;
61 | private_key_dst[31] &= 63;
62 | private_key_dst[31] |= 64;
63 |
64 | ge_scalarmult_base(&A, private_key_dst);
65 | ge_p3_tobytes(public_key_dst, &A); //working, public key matched maria server.
66 | }
67 |
68 | //#include "core/templates/vector.h"
69 | //
70 | //
71 | ////
72 | //void ed25519_sign_msg(const Vector pwd_sha512_src, const Vector message_src, Vector signature_dst) {
73 | // Vector private_key;
74 | // Vector public_key;
75 | //
76 | // ed25519_create_keypair(pwd_sha512_src, private_key, public_key);
77 | // ed25519_sign(message_src.ptr(), message_src.size(), public_key.ptrw(), private_key.ptrw(), signature_dst.ptrw());
78 | //}
79 | //
80 | //void ed25519_create_keypair(const Vector pwd_sha512_src, Vector private_key_dst, Vector public_key_dst) {
81 | // /*REF RFC 8032 5.1.5 Key Generation https://tools.ietf.org/html/rfc8032#page-13
82 | // * The referenced private key that is ran thru sha512 is the password, since we are storing the hashed password
83 | // * in the module in case of a needed reconnection, the 1st step in RFC Key Generation will be skipped here.
84 | // */
85 | //
86 | // ge_p3 A;
87 | // private_key_dst = pwd_sha512_src.slice(0);
88 | //
89 | // /*Step 2 of the RFC
90 | // * It references the first and last bits, but that is after pruning,
91 | // * I cheated and skipped pruning and reused the variable for the scalar functions.
92 | // */
93 | // private_key_dst.set(0, private_key_dst[0] & 248);
94 | // private_key_dst.set(31, private_key_dst[0] & 63);
95 | // private_key_dst.set(31, private_key_dst[0] | 248);
96 | //
97 | //
98 | // ge_scalarmult_base(&A, private_key_dst.ptr());
99 | // ge_p3_tobytes(public_key_dst.ptrw(), &A); //working, public key matched maria server.
100 | //}
101 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Godot executables
2 | *.exe
3 | *.64
4 | *.x86_64
5 | *.app
6 |
7 | # Godot-specific ignores
8 | *.pck
9 | .import/
10 | .godot/
11 | */.import/
12 | export.cfg
13 | export_presets.cfg
14 |
15 | ## Ignore Visual Studio temporary files, build results, and
16 | ## files generated by popular Visual Studio add-ons.
17 | ##
18 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
19 |
20 | # User-specific files
21 | *.rsuser
22 | *.suo
23 | *.user
24 | *.userosscache
25 | *.sln.docstates
26 |
27 | # User-specific files (MonoDevelop/Xamarin Studio)
28 | *.userprefs
29 |
30 | # Mono auto generated files
31 | mono_crash.*
32 |
33 | # Build results
34 | [Dd]ebug/
35 | [Dd]ebugPublic/
36 | [Rr]elease/
37 | [Rr]eleases/
38 | x64/
39 | x86/
40 | [Aa][Rr][Mm]/
41 | [Aa][Rr][Mm]64/
42 | bld/
43 | [Bb]in/
44 | [Oo]bj/
45 | [Ll]og/
46 | [Ll]ogs/
47 | *.o
48 |
49 | # VSCode
50 | *.vscode
51 |
52 | # Visual Studio 2015/2017 cache/options directory
53 | .vs/
54 | # Uncomment if you have tasks that create the project's static files in wwwroot
55 | #wwwroot/
56 |
57 | # Visual Studio 2017 auto generated files
58 | Generated\ Files/
59 |
60 | # MSTest test Results
61 | [Tt]est[Rr]esult*/
62 | [Bb]uild[Ll]og.*
63 |
64 | # NUnit
65 | *.VisualState.xml
66 | TestResult.xml
67 | nunit-*.xml
68 |
69 | # Build Results of an ATL Project
70 | [Dd]ebugPS/
71 | [Rr]eleasePS/
72 | dlldata.c
73 |
74 | # Benchmark Results
75 | BenchmarkDotNet.Artifacts/
76 |
77 | # .NET Core
78 | project.lock.json
79 | project.fragment.lock.json
80 | artifacts/
81 |
82 | # StyleCop
83 | StyleCopReport.xml
84 |
85 | # Files built by Visual Studio
86 | *_i.c
87 | *_p.c
88 | *_h.h
89 | *.ilk
90 | *.meta
91 | *.obj
92 | *.iobj
93 | *.pch
94 | *.pdb
95 | *.ipdb
96 | *.pgc
97 | *.pgd
98 | *.rsp
99 | *.sbr
100 | *.tlb
101 | *.tli
102 | *.tlh
103 | *.tmp
104 | *.tmp_proj
105 | *_wpftmp.csproj
106 | *.log
107 | *.vspscc
108 | *.vssscc
109 | .builds
110 | *.pidb
111 | *.svclog
112 | *.scc
113 |
114 | # Chutzpah Test files
115 | _Chutzpah*
116 |
117 | # Visual C++ cache files
118 | ipch/
119 | *.aps
120 | *.ncb
121 | *.opendb
122 | *.opensdf
123 | *.sdf
124 | *.cachefile
125 | *.VC.db
126 | *.VC.VC.opendb
127 |
128 | # Visual Studio profiler
129 | *.psess
130 | *.vsp
131 | *.vspx
132 | *.sap
133 |
134 | # Visual Studio Trace Files
135 | *.e2e
136 |
137 | # TFS 2012 Local Workspace
138 | $tf/
139 |
140 | # Guidance Automation Toolkit
141 | *.gpState
142 |
143 | # ReSharper is a .NET coding add-in
144 | _ReSharper*/
145 | *.[Rr]e[Ss]harper
146 | *.DotSettings.user
147 |
148 | # TeamCity is a build add-in
149 | _TeamCity*
150 |
151 | # DotCover is a Code Coverage Tool
152 | *.dotCover
153 |
154 | # AxoCover is a Code Coverage Tool
155 | .axoCover/*
156 | !.axoCover/settings.json
157 |
158 | # Visual Studio code coverage results
159 | *.coverage
160 | *.coveragexml
161 |
162 | # NCrunch
163 | _NCrunch_*
164 | .*crunch*.local.xml
165 | nCrunchTemp_*
166 |
167 | # MightyMoose
168 | *.mm.*
169 | AutoTest.Net/
170 |
171 | # Web workbench (sass)
172 | .sass-cache/
173 |
174 | # Installshield output folder
175 | [Ee]xpress/
176 |
177 | # DocProject is a documentation generator add-in
178 | DocProject/buildhelp/
179 | DocProject/Help/*.HxT
180 | DocProject/Help/*.HxC
181 | DocProject/Help/*.hhc
182 | DocProject/Help/*.hhk
183 | DocProject/Help/*.hhp
184 | DocProject/Help/Html2
185 | DocProject/Help/html
186 |
187 | # Click-Once directory
188 | publish/
189 |
190 | # Publish Web Output
191 | *.[Pp]ublish.xml
192 | *.azurePubxml
193 | # Note: Comment the next line if you want to checkin your web deploy settings,
194 | # but database connection strings (with potential passwords) will be unencrypted
195 | *.pubxml
196 | *.publishproj
197 |
198 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
199 | # checkin your Azure Web App publish settings, but sensitive information contained
200 | # in these scripts will be unencrypted
201 | PublishScripts/
202 |
203 | # NuGet Packages
204 | *.nupkg
205 | # NuGet Symbol Packages
206 | *.snupkg
207 | # The packages folder can be ignored because of Package Restore
208 | **/[Pp]ackages/*
209 | # except build/, which is used as an MSBuild target.
210 | !**/[Pp]ackages/build/
211 | # Uncomment if necessary however generally it will be regenerated when needed
212 | #!**/[Pp]ackages/repositories.config
213 | # NuGet v3's project.json files produces more ignorable files
214 | *.nuget.props
215 | *.nuget.targets
216 |
217 | # Microsoft Azure Build Output
218 | csx/
219 | *.build.csdef
220 |
221 | # Microsoft Azure Emulator
222 | ecf/
223 | rcf/
224 |
225 | # Windows Store app package directories and files
226 | AppPackages/
227 | BundleArtifacts/
228 | Package.StoreAssociation.xml
229 | _pkginfo.txt
230 | *.appx
231 | *.appxbundle
232 | *.appxupload
233 |
234 | # Visual Studio cache files
235 | # files ending in .cache can be ignored
236 | *.[Cc]ache
237 | # but keep track of directories ending in .cache
238 | !?*.[Cc]ache/
239 |
240 | # Others
241 | ClientBin/
242 | ~$*
243 | *~
244 | *.dbmdl
245 | *.dbproj.schemaview
246 | *.jfm
247 | *.pfx
248 | *.publishsettings
249 | orleans.codegen.cs
250 |
251 | # Including strong name files can present a security risk
252 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
253 | #*.snk
254 |
255 | # Since there are multiple workflows, uncomment next line to ignore bower_components
256 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
257 | #bower_components/
258 |
259 | # RIA/Silverlight projects
260 | Generated_Code/
261 |
262 | # Backup & report files from converting an old project file
263 | # to a newer Visual Studio version. Backup files are not needed,
264 | # because we have git ;-)
265 | _UpgradeReport_Files/
266 | Backup*/
267 | UpgradeLog*.XML
268 | UpgradeLog*.htm
269 | ServiceFabricBackup/
270 | *.rptproj.bak
271 |
272 | # SQL Server files
273 | *.mdf
274 | *.ldf
275 | *.ndf
276 |
277 | # Business Intelligence projects
278 | *.rdl.data
279 | *.bim.layout
280 | *.bim_*.settings
281 | *.rptproj.rsuser
282 | *- [Bb]ackup.rdl
283 | *- [Bb]ackup ([0-9]).rdl
284 | *- [Bb]ackup ([0-9][0-9]).rdl
285 |
286 | # Microsoft Fakes
287 | FakesAssemblies/
288 |
289 | # GhostDoc plugin setting file
290 | *.GhostDoc.xml
291 |
292 | # Node.js Tools for Visual Studio
293 | .ntvs_analysis.dat
294 | node_modules/
295 |
296 | # Visual Studio 6 build log
297 | *.plg
298 |
299 | # Visual Studio 6 workspace options file
300 | *.opt
301 |
302 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
303 | *.vbw
304 |
305 | # Visual Studio LightSwitch build output
306 | **/*.HTMLClient/GeneratedArtifacts
307 | **/*.DesktopClient/GeneratedArtifacts
308 | **/*.DesktopClient/ModelManifest.xml
309 | **/*.Server/GeneratedArtifacts
310 | **/*.Server/ModelManifest.xml
311 | _Pvt_Extensions
312 |
313 | # Paket dependency manager
314 | .paket/paket.exe
315 | paket-files/
316 |
317 | # FAKE - F# Make
318 | .fake/
319 |
320 | # CodeRush personal settings
321 | .cr/personal
322 |
323 | # Python Tools for Visual Studio (PTVS)
324 | __pycache__/
325 | *.pyc
326 |
327 | # Cake - Uncomment if you are using it
328 | # tools/**
329 | # !tools/packages.config
330 |
331 | # Tabs Studio
332 | *.tss
333 |
334 | # Telerik's JustMock configuration file
335 | *.jmconfig
336 |
337 | # BizTalk build output
338 | *.btp.cs
339 | *.btm.cs
340 | *.odx.cs
341 | *.xsd.cs
342 |
343 | # OpenCover UI analysis results
344 | OpenCover/
345 |
346 | # Azure Stream Analytics local run output
347 | ASALocalRun/
348 |
349 | # MSBuild Binary and Structured Log
350 | *.binlog
351 |
352 | # NVidia Nsight GPU debugger configuration file
353 | *.nvuser
354 |
355 | # MFractors (Xamarin productivity tool) working folder
356 | .mfractor/
357 |
358 | # Local History for Visual Studio
359 | .localhistory/
360 |
361 | # BeatPulse healthcheck temp database
362 | healthchecksdb
363 |
364 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
365 | MigrationBackup/
366 |
367 | # Ionide (cross platform F# VS Code tools) working folder
368 | .ionide/
369 |
--------------------------------------------------------------------------------
/mariadb.h:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* mariadb.h */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | //TODO(sigrudds1) Add sha256 Authentication for MySQL alternative authentication
32 | //TODO(sigrudds1) Add cashing_sha2_password for MySQL alternative authentication
33 | //TODO(sigrudds1) Use virtuallock(windows) or mlock(linux) to prevent memory dump of username and password
34 | //TODO(sigrudds1) ASYNC callbacks using the username, signals maybe.
35 |
36 | #ifndef MARIADB_H
37 | #define MARIADB_H
38 |
39 | #define DEBUG_OUTPUT
40 |
41 | #include
42 | #include
43 | #include
44 | // #include "core/os/thread.h"
45 | // #include "core/os/mutex.h"
46 | #include "core/object/ref_counted.h"
47 | #include "core/string/ustring.h"
48 | #include "core/templates/vector.h"
49 | #include "core/variant/variant.h"
50 |
51 |
52 | constexpr uint8_t kCharacterCollationId = 33; //utf8_general_ci
53 | constexpr char *kCharacterCollationName = (char *)"utf8_general_ci";
54 |
55 | class MariaDB : public RefCounted {
56 | GDCLASS(MariaDB, RefCounted);
57 |
58 | public:
59 | enum AuthType {
60 | AUTH_TYPE_ED25519,
61 | AUTH_TYPE_MYSQL_NATIVE,
62 | AUTH_TYPE_LAST,
63 | };
64 |
65 | enum IpType {
66 | IP_TYPE_IPV4 = IP::TYPE_IPV4,
67 | IP_TYPE_IPV6 = IP::TYPE_IPV6,
68 | IP_TYPE_ANY = IP::TYPE_ANY,
69 | };
70 |
71 | enum ErrorCodes {
72 | OK = 0,
73 | ERR_NO_RESPONSE,
74 | ERR_NOT_CONNECTED,
75 | ERR_PACKET_LENGTH_MISMATCH,
76 | ERR_PACKET_SEQUENCE_ERROR,
77 | ERR_SERVER_PROTOCOL_INCOMPATIBLE,
78 | ERR_CLIENT_PROTOCOL_INCOMPATIBLE,
79 | ERR_AUTH_PLUGIN_NOT_SET,
80 | ERR_AUTH_PLUGIN_INCOMPATIBLE,
81 | ERR_AUTH_FAILED,
82 | ERR_USERNAME_EMPTY,
83 | ERR_PASSWORD_EMPTY,
84 | ERR_DB_EMPTY
85 | };
86 |
87 | private:
88 | //https://mariadb.com/kb/en/connection/#capabilities
89 | enum class Capabilities : uint64_t {
90 | LONG_PASSWORD = (1UL << 0), //MySQL
91 | CLIENT_MYSQL = (1UL << 0), //MariaDB - lets server know this is a mysql client
92 | FOUND_ROWS = (1UL << 1),
93 | LONG_FLAG = (1UL << 2), //Not listed in MariaDB
94 | CONNECT_WITH_DB = (1UL << 3),
95 | NO_SCHEMA = (1UL << 4), //Not listed in MariaDB
96 | NO_DB_TABLE_COLUMN = (1UL << 4), //Alternate name, Not listed in MariaDB
97 | COMPRESS = (1UL << 5),
98 | ODBC = (1UL << 6), //Not listed in MariaDB
99 | LOCAL_FILES = (1UL << 7),
100 | IGNORE_SPACE = (1UL << 8),
101 | CLIENT_PROTOCOL_41 = (1UL << 9),
102 | CLIENT_INTERACTIVE = (1UL << 10),
103 | SSL = (1UL << 11),
104 | IGNORE_SIGPIPE = (1UL << 12), //MySQL
105 | TRANSACTIONS_MARIA = (1UL << 12), //MariaDB
106 | TRANSACTIONS_MYSQL = (1UL << 13), //MySQL
107 | SECURE_CONNECTION = (1UL << 13), //MariaDB
108 | RESERVED = (1UL << 14), //Not listed in MariaDB
109 | RESERVED2 = (1UL << 15), //Not in Maria Docs but needed
110 | MULTI_STATEMENTS = (1UL << 16),
111 | MULTI_RESULTS = (1UL << 17),
112 | PS_MULTI_RESULTS = (1UL << 18),
113 | PLUGIN_AUTH = (1UL << 19),
114 | CLIENT_SEND_CONNECT_ATTRS = (1UL << 20),
115 | PLUGIN_AUTH_LENENC_CLIENT_DATA = (1UL << 21), //TODO Add compatibility
116 | CAN_HANDLE_EXPIRED_PASSWORDS = (1UL << 22), //Not listed in MariaDB
117 | SESSION_TRACK = (1UL << 23),
118 | CLIENT_DEPRECATE_EOF = (1UL << 24),
119 | OPTIONAL_RESULTSET_METADATA = (1UL << 25),
120 | CLIENT_ZSTD_COMPRESSION_ALGORITHM = (1UL << 26),
121 | CLIENT_QUERY_ATTRIBUTES = (1UL << 27), //Not listed in MariaDB
122 | //NOT_USED = (1UL << 28),
123 | CLIENT_CAPABILITY_EXTENSION = (1UL << 29), //MariaDB reserved for future use.
124 | SSL_VERIFY_SERVER_CERT = (1UL << 30), //Not listed in MariaDB
125 | REMEMBER_OPTIONS = (1UL << 31), //Not listed in MariaDB
126 | MARIADB_CLIENT_PROGRESS = (1UL << 32),
127 | MARIADB_CLIENT_COM_MULTI = (1UL << 33),
128 | MARIADB_CLIENT_STMT_BULK_OPERATIONS = (1UL << 34),
129 | MARIADB_CLIENT_EXTENDED_TYPE_INFO = (1UL << 35),
130 | MARIADB_CLIENT_CACHE_METADATA = (1UL << 36)
131 | };
132 |
133 | struct ColumnData {
134 | String name;
135 | uint16_t char_set;
136 | uint8_t field_type;
137 | };
138 |
139 | const Vector kAuthTypeNames = { "client_ed25519", "mysql_native_password" };
140 | bool _dbl_to_string = false;
141 | IpType _ip_type = IpType::IP_TYPE_ANY;
142 | AuthType _client_auth_type = AUTH_TYPE_ED25519;
143 | bool _is_pre_hashed = true;
144 | bool _authenticated = false;
145 | uint64_t _client_capabilities = 0;
146 | //uint32_t _client_extended_capabilities = 0;
147 | uint64_t _server_capabilities = 0;
148 | //uint32_t _server_extended_capabilities = 0;
149 |
150 | Vector _username;
151 | Vector _password_hashed;
152 | Vector _dbname;
153 |
154 | // Ref tcp_connection;
155 |
156 | StreamPeerTCP _stream;
157 | IPAddress _ip;
158 | int _port = 0;
159 |
160 | // bool _running = true;
161 | // bool _tcp_polling = false;
162 | // Mutex _tcp_mutex;
163 | // Thread _tcp_thread;
164 | // Vector _tcp_thread_data;
165 |
166 | String _protocol_ver;
167 | String _server_ver_str;
168 | uint8_t _srvr_major_ver = 0;
169 | uint8_t _srvr_minor_ver = 0;
170 | String _last_query;
171 | Vector _last_query_converted;
172 | Vector _last_transmitted;
173 | Vector _last_response;
174 |
175 |
176 | /**
177 | * \brief Adds the packet size and sequence number to the beginning of the packet,
178 | * it must be used once just before sending stream to server.
179 | * \param stream std::vector the stream to be modified.
180 | * \param sequance int
181 | */
182 | void m_add_packet_header(Vector &p_pkt, uint8_t p_pkt_seq);
183 |
184 | // void m_append_thread_data(PackedByteArray &p_data, const uint64_t p_timeout = 1000);
185 |
186 | uint32_t m_chk_rcv_bfr(Vector &bfr, int &bfr_size, const size_t cur_pos, const size_t need);
187 |
188 | Error m_client_protocol_v41(const AuthType p_srvr_auth_type, const Vector p_srvr_salt);
189 | Error m_connect();
190 | static void m_tcp_thread_func(void *instance);
191 |
192 | String m_find_vbytes_str_at(Vector p_buf, size_t &p_start_pos);
193 | String m_find_vbytes_str(Vector p_buf);
194 |
195 | PackedByteArray m_get_pkt_bytes(const Vector &src_buf, size_t &start_pos, const size_t byte_cnt);
196 | size_t m_get_pkt_len_at(const Vector p_src_buf, size_t &p_start_pos);
197 | AuthType m_get_server_auth_type(String p_srvr_auth_name);
198 | Variant m_get_type_data(const int p_db_field_type, const PackedByteArray p_data);
199 |
200 | Vector m_recv_data();
201 | Vector m_recv_data(uint32_t p_timeout);
202 | //TODO(sigrudds1) Add error log file using the username in the filename
203 | void m_handle_server_error(const Vector p_src_buffer, size_t &p_last_pos);
204 | Error m_server_init_handshake_v10(const Vector &p_src_buffer);
205 | void m_update_password(String p_password);
206 | void m_update_username(String P_username);
207 |
208 | protected:
209 | static void _bind_methods();
210 |
211 | public:
212 | /**
213 | * \brief This method sets the authentication type used.
214 | *
215 | * \param host
216 | * \param port
217 | * \param dbname
218 | * \param username
219 | * \param password
220 | * \param auth_type enum AuthType determines what authoriztion type will be statically used.
221 | * \param is_pre_hash bool if set the password used will be hashed by the required type before used.
222 | * \return uint32_t 0 = no error, see error enum class ErrorCode
223 | */
224 | Error connect_db(String host, int port, String dbname, String username, String password,
225 | AuthType auth_type = AuthType::AUTH_TYPE_ED25519, bool is_prehashed = true);
226 | void disconnect_db();
227 |
228 | String get_last_query();
229 | PackedByteArray get_last_query_converted();
230 | PackedByteArray get_last_response();
231 | PackedByteArray get_last_transmitted();
232 |
233 | bool is_connected_db();
234 |
235 | Variant query(String sql_stmt);
236 |
237 |
238 | //TODO(sigrudds1) Implement SSL/TLS
239 | //void tls_enable(bool enable);
240 |
241 | void set_dbl_to_string(bool is_to_str);
242 | void set_db_name(String p_db_name);
243 | void set_ip_type(IpType p_type);
244 | //TODO(sigrudds1) Async Callbacks
245 |
246 | MariaDB();
247 | ~MariaDB();
248 | };
249 |
250 | VARIANT_ENUM_CAST(MariaDB::AuthType);
251 | VARIANT_ENUM_CAST(MariaDB::IpType);
252 |
253 | #endif
254 |
--------------------------------------------------------------------------------
/examples/G4_MariaDB_test/create_db.sql.txt:
--------------------------------------------------------------------------------
1 | INSTALL PLUGIN IF NOT EXISTS ed25519 SONAME 'auth_ed25519';
2 |
3 | CREATE DATABASE IF NOT EXISTS `Godot_Test` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */;
4 |
5 | CREATE TABLE IF NOT EXISTS Godot_Test.`many_columns` (
6 | `Column1` int(11) DEFAULT NULL,
7 | `Column2` int(11) DEFAULT NULL,
8 | `Column3` int(11) DEFAULT NULL,
9 | `Column4` int(11) DEFAULT NULL,
10 | `Column5` int(11) DEFAULT NULL,
11 | `Column6` int(11) DEFAULT NULL,
12 | `Column7` int(11) DEFAULT NULL,
13 | `Column8` int(11) DEFAULT NULL,
14 | `Column9` int(11) DEFAULT NULL,
15 | `Column10` int(11) DEFAULT NULL,
16 | `Column11` int(11) DEFAULT NULL,
17 | `Column12` int(11) DEFAULT NULL,
18 | `Column13` int(11) DEFAULT NULL,
19 | `Column14` int(11) DEFAULT NULL,
20 | `Column15` int(11) DEFAULT NULL,
21 | `Column16` int(11) DEFAULT NULL,
22 | `Column17` int(11) DEFAULT NULL,
23 | `Column18` int(11) DEFAULT NULL,
24 | `Column19` int(11) DEFAULT NULL,
25 | `Column20` int(11) DEFAULT NULL,
26 | `Column21` int(11) DEFAULT NULL,
27 | `Column22` int(11) DEFAULT NULL,
28 | `Column23` int(11) DEFAULT NULL,
29 | `Column24` int(11) DEFAULT NULL,
30 | `Column25` int(11) DEFAULT NULL,
31 | `Column26` int(11) DEFAULT NULL,
32 | `Column27` int(11) DEFAULT NULL,
33 | `Column28` int(11) DEFAULT NULL,
34 | `Column29` int(11) DEFAULT NULL,
35 | `Column30` int(11) DEFAULT NULL,
36 | `Column31` int(11) DEFAULT NULL,
37 | `Column32` int(11) DEFAULT NULL,
38 | `Column33` int(11) DEFAULT NULL,
39 | `Column34` int(11) DEFAULT NULL,
40 | `Column35` int(11) DEFAULT NULL,
41 | `Column36` int(11) DEFAULT NULL,
42 | `Column37` int(11) DEFAULT NULL,
43 | `Column38` int(11) DEFAULT NULL,
44 | `Column39` int(11) DEFAULT NULL,
45 | `Column40` int(11) DEFAULT NULL,
46 | `Column41` int(11) DEFAULT NULL,
47 | `Column42` int(11) DEFAULT NULL,
48 | `Column43` int(11) DEFAULT NULL,
49 | `Column44` int(11) DEFAULT NULL,
50 | `Column45` int(11) DEFAULT NULL,
51 | `Column46` int(11) DEFAULT NULL,
52 | `Column47` int(11) DEFAULT NULL,
53 | `Column48` int(11) DEFAULT NULL,
54 | `Column49` int(11) DEFAULT NULL,
55 | `Column50` int(11) DEFAULT NULL,
56 | `Column51` int(11) DEFAULT NULL,
57 | `Column52` int(11) DEFAULT NULL,
58 | `Column53` int(11) DEFAULT NULL,
59 | `Column54` int(11) DEFAULT NULL,
60 | `Column55` int(11) DEFAULT NULL,
61 | `Column56` int(11) DEFAULT NULL,
62 | `Column57` int(11) DEFAULT NULL,
63 | `Column58` int(11) DEFAULT NULL,
64 | `Column59` int(11) DEFAULT NULL,
65 | `Column60` int(11) DEFAULT NULL,
66 | `Column61` int(11) DEFAULT NULL,
67 | `Column62` int(11) DEFAULT NULL,
68 | `Column63` int(11) DEFAULT NULL,
69 | `Column64` int(11) DEFAULT NULL,
70 | `Column65` int(11) DEFAULT NULL,
71 | `Column66` int(11) DEFAULT NULL,
72 | `Column67` int(11) DEFAULT NULL,
73 | `Column68` int(11) DEFAULT NULL,
74 | `Column69` int(11) DEFAULT NULL,
75 | `Column70` int(11) DEFAULT NULL,
76 | `Column71` int(11) DEFAULT NULL,
77 | `Column72` int(11) DEFAULT NULL,
78 | `Column73` int(11) DEFAULT NULL,
79 | `Column74` int(11) DEFAULT NULL,
80 | `Column75` int(11) DEFAULT NULL,
81 | `Column76` int(11) DEFAULT NULL,
82 | `Column77` int(11) DEFAULT NULL,
83 | `Column78` int(11) DEFAULT NULL,
84 | `Column79` int(11) DEFAULT NULL,
85 | `Column80` int(11) DEFAULT NULL,
86 | `Column81` int(11) DEFAULT NULL,
87 | `Column82` int(11) DEFAULT NULL,
88 | `Column83` int(11) DEFAULT NULL,
89 | `Column84` int(11) DEFAULT NULL,
90 | `Column85` int(11) DEFAULT NULL,
91 | `Column86` int(11) DEFAULT NULL,
92 | `Column87` int(11) DEFAULT NULL,
93 | `Column88` int(11) DEFAULT NULL,
94 | `Column89` int(11) DEFAULT NULL,
95 | `Column90` int(11) DEFAULT NULL,
96 | `Column91` int(11) DEFAULT NULL,
97 | `Column92` int(11) DEFAULT NULL,
98 | `Column93` int(11) DEFAULT NULL,
99 | `Column94` int(11) DEFAULT NULL,
100 | `Column95` int(11) DEFAULT NULL,
101 | `Column96` int(11) DEFAULT NULL,
102 | `Column97` int(11) DEFAULT NULL,
103 | `Column98` int(11) DEFAULT NULL,
104 | `Column99` int(11) DEFAULT NULL,
105 | `Column100` int(11) DEFAULT NULL,
106 | `Column101` int(11) DEFAULT NULL,
107 | `Column102` int(11) DEFAULT NULL,
108 | `Column103` int(11) DEFAULT NULL,
109 | `Column104` int(11) DEFAULT NULL,
110 | `Column105` int(11) DEFAULT NULL,
111 | `Column106` int(11) DEFAULT NULL,
112 | `Column107` int(11) DEFAULT NULL,
113 | `Column108` int(11) DEFAULT NULL,
114 | `Column109` int(11) DEFAULT NULL,
115 | `Column110` int(11) DEFAULT NULL,
116 | `Column111` int(11) DEFAULT NULL,
117 | `Column112` int(11) DEFAULT NULL,
118 | `Column113` int(11) DEFAULT NULL,
119 | `Column114` int(11) DEFAULT NULL,
120 | `Column115` int(11) DEFAULT NULL,
121 | `Column116` int(11) DEFAULT NULL,
122 | `Column117` int(11) DEFAULT NULL,
123 | `Column118` int(11) DEFAULT NULL,
124 | `Column119` int(11) DEFAULT NULL,
125 | `Column120` int(11) DEFAULT NULL,
126 | `Column121` int(11) DEFAULT NULL,
127 | `Column122` int(11) DEFAULT NULL,
128 | `Column123` int(11) DEFAULT NULL,
129 | `Column124` int(11) DEFAULT NULL,
130 | `Column125` int(11) DEFAULT NULL,
131 | `Column126` int(11) DEFAULT NULL,
132 | `Column127` int(11) DEFAULT NULL,
133 | `Column128` int(11) DEFAULT NULL,
134 | `Column129` int(11) DEFAULT NULL,
135 | `Column130` int(11) DEFAULT NULL,
136 | `Column131` int(11) DEFAULT NULL,
137 | `Column132` int(11) DEFAULT NULL,
138 | `Column133` int(11) DEFAULT NULL,
139 | `Column134` int(11) DEFAULT NULL,
140 | `Column135` int(11) DEFAULT NULL,
141 | `Column136` int(11) DEFAULT NULL,
142 | `Column137` int(11) DEFAULT NULL,
143 | `Column138` int(11) DEFAULT NULL,
144 | `Column139` int(11) DEFAULT NULL,
145 | `Column140` int(11) DEFAULT NULL,
146 | `Column141` int(11) DEFAULT NULL,
147 | `Column142` int(11) DEFAULT NULL,
148 | `Column143` int(11) DEFAULT NULL,
149 | `Column144` int(11) DEFAULT NULL,
150 | `Column145` int(11) DEFAULT NULL,
151 | `Column146` int(11) DEFAULT NULL,
152 | `Column147` int(11) DEFAULT NULL,
153 | `Column148` int(11) DEFAULT NULL,
154 | `Column149` int(11) DEFAULT NULL,
155 | `Column150` int(11) DEFAULT NULL,
156 | `Column151` int(11) DEFAULT NULL,
157 | `Column152` int(11) DEFAULT NULL,
158 | `Column153` int(11) DEFAULT NULL,
159 | `Column154` int(11) DEFAULT NULL,
160 | `Column155` int(11) DEFAULT NULL,
161 | `Column156` int(11) DEFAULT NULL,
162 | `Column157` int(11) DEFAULT NULL,
163 | `Column158` int(11) DEFAULT NULL,
164 | `Column159` int(11) DEFAULT NULL,
165 | `Column160` int(11) DEFAULT NULL,
166 | `Column161` int(11) DEFAULT NULL,
167 | `Column162` int(11) DEFAULT NULL,
168 | `Column163` int(11) DEFAULT NULL,
169 | `Column164` int(11) DEFAULT NULL,
170 | `Column165` int(11) DEFAULT NULL,
171 | `Column166` int(11) DEFAULT NULL,
172 | `Column167` int(11) DEFAULT NULL,
173 | `Column168` int(11) DEFAULT NULL,
174 | `Column169` int(11) DEFAULT NULL,
175 | `Column170` int(11) DEFAULT NULL,
176 | `Column171` int(11) DEFAULT NULL,
177 | `Column172` int(11) DEFAULT NULL,
178 | `Column173` int(11) DEFAULT NULL,
179 | `Column174` int(11) DEFAULT NULL,
180 | `Column175` int(11) DEFAULT NULL,
181 | `Column176` int(11) DEFAULT NULL,
182 | `Column177` int(11) DEFAULT NULL,
183 | `Column178` int(11) DEFAULT NULL,
184 | `Column179` int(11) DEFAULT NULL,
185 | `Column180` int(11) DEFAULT NULL,
186 | `Column181` int(11) DEFAULT NULL,
187 | `Column182` int(11) DEFAULT NULL,
188 | `Column183` int(11) DEFAULT NULL,
189 | `Column184` int(11) DEFAULT NULL,
190 | `Column185` int(11) DEFAULT NULL,
191 | `Column186` int(11) DEFAULT NULL,
192 | `Column187` int(11) DEFAULT NULL,
193 | `Column188` int(11) DEFAULT NULL,
194 | `Column189` int(11) DEFAULT NULL,
195 | `Column190` int(11) DEFAULT NULL,
196 | `Column191` int(11) DEFAULT NULL,
197 | `Column192` int(11) DEFAULT NULL,
198 | `Column193` int(11) DEFAULT NULL,
199 | `Column194` int(11) DEFAULT NULL,
200 | `Column195` int(11) DEFAULT NULL,
201 | `Column196` int(11) DEFAULT NULL,
202 | `Column197` int(11) DEFAULT NULL,
203 | `Column198` int(11) DEFAULT NULL,
204 | `Column199` int(11) DEFAULT NULL,
205 | `Column200` int(11) DEFAULT NULL,
206 | `Column201` int(11) DEFAULT NULL,
207 | `Column202` int(11) DEFAULT NULL,
208 | `Column203` int(11) DEFAULT NULL,
209 | `Column204` int(11) DEFAULT NULL,
210 | `Column205` int(11) DEFAULT NULL,
211 | `Column206` int(11) DEFAULT NULL,
212 | `Column207` int(11) DEFAULT NULL,
213 | `Column208` int(11) DEFAULT NULL,
214 | `Column209` int(11) DEFAULT NULL,
215 | `Column210` int(11) DEFAULT NULL,
216 | `Column211` int(11) DEFAULT NULL,
217 | `Column212` int(11) DEFAULT NULL,
218 | `Column213` int(11) DEFAULT NULL,
219 | `Column214` int(11) DEFAULT NULL,
220 | `Column215` int(11) DEFAULT NULL,
221 | `Column216` int(11) DEFAULT NULL,
222 | `Column217` int(11) DEFAULT NULL,
223 | `Column218` int(11) DEFAULT NULL,
224 | `Column219` int(11) DEFAULT NULL,
225 | `Column220` int(11) DEFAULT NULL,
226 | `Column221` int(11) DEFAULT NULL,
227 | `Column222` int(11) DEFAULT NULL,
228 | `Column223` int(11) DEFAULT NULL,
229 | `Column224` int(11) DEFAULT NULL,
230 | `Column225` int(11) DEFAULT NULL,
231 | `Column226` int(11) DEFAULT NULL,
232 | `Column227` int(11) DEFAULT NULL,
233 | `Column228` int(11) DEFAULT NULL,
234 | `Column229` int(11) DEFAULT NULL,
235 | `Column230` int(11) DEFAULT NULL,
236 | `Column231` int(11) DEFAULT NULL,
237 | `Column232` int(11) DEFAULT NULL,
238 | `Column233` int(11) DEFAULT NULL,
239 | `Column234` int(11) DEFAULT NULL,
240 | `Column235` int(11) DEFAULT NULL,
241 | `Column236` int(11) DEFAULT NULL,
242 | `Column237` int(11) DEFAULT NULL,
243 | `Column238` int(11) DEFAULT NULL,
244 | `Column239` int(11) DEFAULT NULL,
245 | `Column240` int(11) DEFAULT NULL,
246 | `Column241` int(11) DEFAULT NULL,
247 | `Column242` int(11) DEFAULT NULL,
248 | `Column243` int(11) DEFAULT NULL,
249 | `Column244` int(11) DEFAULT NULL,
250 | `Column245` int(11) DEFAULT NULL,
251 | `Column246` int(11) DEFAULT NULL,
252 | `Column247` int(11) DEFAULT NULL,
253 | `Column248` int(11) DEFAULT NULL,
254 | `Column249` int(11) DEFAULT NULL,
255 | `Column250` int(11) DEFAULT NULL,
256 | `Column251` int(11) DEFAULT NULL,
257 | `Column252` int(11) DEFAULT NULL
258 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
259 |
260 | CREATE TABLE IF NOT EXISTS Godot_Test.`many_records` (
261 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
262 | `type` smallint(5) unsigned NOT NULL,
263 | `zone_id` int(10) unsigned NOT NULL,
264 | `player_id` smallint(5) unsigned DEFAULT NULL,
265 | `map_id` tinyint(3) unsigned NOT NULL,
266 | `text_field` text DEFAULT NULL,
267 | PRIMARY KEY (`id`)
268 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
269 |
270 | CREATE USER IF NOT EXISTS `godot_user`@'localhost' IDENTIFIED VIA ed25519 USING PASSWORD('secret');
271 | CREATE USER IF NOT EXISTS `godot_user`@'::1' IDENTIFIED VIA ed25519 USING PASSWORD('secret');
272 | GRANT ALL PRIVILEGES ON `Godot_Test`.* TO 'godot_user'@'localhost';
273 | GRANT ALL PRIVILEGES ON `Godot_Test`.* TO 'godot_user'@'::1';
274 |
--------------------------------------------------------------------------------
/ed25519_ref10/ed25519_ge.cpp:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* ed25519_ge.cpp */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | /* This file was derived from information found at */
32 | /* https://tools.ietf.org/html/rfc8032 */
33 |
34 | #include
35 |
36 | #include "ed25519_ge.h"
37 | #include "ed25519_precomputed.h"
38 |
39 | /*
40 | r = p + q
41 | */
42 |
43 | void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
44 | fe t0;
45 | fe_add(r->X, p->Y, p->X);
46 | fe_sub(r->Y, p->Y, p->X);
47 | fe_mul(r->Z, r->X, q->YplusX);
48 | fe_mul(r->Y, r->Y, q->YminusX);
49 | fe_mul(r->T, q->T2d, p->T);
50 | fe_mul(r->X, p->Z, q->Z);
51 | fe_add(t0, r->X, r->X);
52 | fe_sub(r->X, r->Z, r->Y);
53 | fe_add(r->Y, r->Z, r->Y);
54 | fe_add(r->Z, t0, r->T);
55 | fe_sub(r->T, t0, r->T);
56 | }
57 |
58 | static void slide(int8_t *r, const uint8_t *a) {
59 | int i;
60 | int b;
61 | int k;
62 |
63 | for (i = 0; i < 256; ++i) {
64 | r[i] = 1 & (a[i >> 3] >> (i & 7));
65 | }
66 |
67 | for (i = 0; i < 256; ++i)
68 | if (r[i]) {
69 | for (b = 1; b <= 6 && i + b < 256; ++b) {
70 | if (r[i + b]) {
71 | if (r[i] + (r[i + b] << b) <= 15) {
72 | r[i] += r[i + b] << b;
73 | r[i + b] = 0;
74 | } else if (r[i] - (r[i + b] << b) >= -15) {
75 | r[i] -= r[i + b] << b;
76 |
77 | for (k = i + b; k < 256; ++k) {
78 | if (!r[k]) {
79 | r[k] = 1;
80 | break;
81 | }
82 |
83 | r[k] = 0;
84 | }
85 | } else {
86 | break;
87 | }
88 | }
89 | }
90 | }
91 | }
92 |
93 | /*
94 | r = a * A + b * B
95 | where a = a[0]+256*a[1]+...+256^31 a[31].
96 | and b = b[0]+256*b[1]+...+256^31 b[31].
97 | B is the Ed25519 base point (x,4/5) with x positive.
98 | */
99 |
100 | void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a, const ge_p3 *A, const uint8_t *b) {
101 | int8_t aslide[256];
102 | int8_t bslide[256];
103 | ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
104 | ge_p1p1 t;
105 | ge_p3 u;
106 | ge_p3 A2;
107 | int i;
108 | slide(aslide, a);
109 | slide(bslide, b);
110 | ge_p3_to_cached(&Ai[0], A);
111 | ge_p3_dbl(&t, A);
112 | ge_p1p1_to_p3(&A2, &t);
113 | ge_add(&t, &A2, &Ai[0]);
114 | ge_p1p1_to_p3(&u, &t);
115 | ge_p3_to_cached(&Ai[1], &u);
116 | ge_add(&t, &A2, &Ai[1]);
117 | ge_p1p1_to_p3(&u, &t);
118 | ge_p3_to_cached(&Ai[2], &u);
119 | ge_add(&t, &A2, &Ai[2]);
120 | ge_p1p1_to_p3(&u, &t);
121 | ge_p3_to_cached(&Ai[3], &u);
122 | ge_add(&t, &A2, &Ai[3]);
123 | ge_p1p1_to_p3(&u, &t);
124 | ge_p3_to_cached(&Ai[4], &u);
125 | ge_add(&t, &A2, &Ai[4]);
126 | ge_p1p1_to_p3(&u, &t);
127 | ge_p3_to_cached(&Ai[5], &u);
128 | ge_add(&t, &A2, &Ai[5]);
129 | ge_p1p1_to_p3(&u, &t);
130 | ge_p3_to_cached(&Ai[6], &u);
131 | ge_add(&t, &A2, &Ai[6]);
132 | ge_p1p1_to_p3(&u, &t);
133 | ge_p3_to_cached(&Ai[7], &u);
134 | ge_p2_0(r);
135 |
136 | for (i = 255; i >= 0; --i) {
137 | if (aslide[i] || bslide[i]) {
138 | break;
139 | }
140 | }
141 |
142 | for (; i >= 0; --i) {
143 | ge_p2_dbl(&t, r);
144 |
145 | if (aslide[i] > 0) {
146 | ge_p1p1_to_p3(&u, &t);
147 | ge_add(&t, &u, &Ai[aslide[i] / 2]);
148 | } else if (aslide[i] < 0) {
149 | ge_p1p1_to_p3(&u, &t);
150 | ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
151 | }
152 |
153 | if (bslide[i] > 0) {
154 | ge_p1p1_to_p3(&u, &t);
155 | ge_madd(&t, &u, &Bi[bslide[i] / 2]);
156 | } else if (bslide[i] < 0) {
157 | ge_p1p1_to_p3(&u, &t);
158 | ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
159 | }
160 |
161 | ge_p1p1_to_p2(r, &t);
162 | }
163 | }
164 |
165 | static const fe d = {
166 | -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116
167 | };
168 |
169 | static const fe sqrtm1 = {
170 | -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482
171 | };
172 |
173 | int ge_frombytes_negate_vartime(ge_p3 *h, const uint8_t *s) {
174 | fe u;
175 | fe v;
176 | fe v3;
177 | fe vxx;
178 | fe check;
179 | fe_frombytes(h->Y, s);
180 | fe_1(h->Z);
181 | fe_sq(u, h->Y);
182 | fe_mul(v, u, d);
183 | fe_sub(u, u, h->Z); /* u = y^2-1 */
184 | fe_add(v, v, h->Z); /* v = dy^2+1 */
185 | fe_sq(v3, v);
186 | fe_mul(v3, v3, v); /* v3 = v^3 */
187 | fe_sq(h->X, v3);
188 | fe_mul(h->X, h->X, v);
189 | fe_mul(h->X, h->X, u); /* x = uv^7 */
190 | fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
191 | fe_mul(h->X, h->X, v3);
192 | fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
193 | fe_sq(vxx, h->X);
194 | fe_mul(vxx, vxx, v);
195 | fe_sub(check, vxx, u); /* vx^2-u */
196 |
197 | if (fe_isnonzero(check)) {
198 | fe_add(check, vxx, u); /* vx^2+u */
199 |
200 | if (fe_isnonzero(check)) {
201 | return -1;
202 | }
203 |
204 | fe_mul(h->X, h->X, sqrtm1);
205 | }
206 |
207 | if (fe_isnegative(h->X) == (s[31] >> 7)) {
208 | fe_neg(h->X, h->X);
209 | }
210 |
211 | fe_mul(h->T, h->X, h->Y);
212 | return 0;
213 | }
214 |
215 | /*
216 | r = p + q
217 | */
218 |
219 | void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
220 | fe t0;
221 | fe_add(r->X, p->Y, p->X);
222 | fe_sub(r->Y, p->Y, p->X);
223 | fe_mul(r->Z, r->X, q->yplusx);
224 | fe_mul(r->Y, r->Y, q->yminusx);
225 | fe_mul(r->T, q->xy2d, p->T);
226 | fe_add(t0, p->Z, p->Z);
227 | fe_sub(r->X, r->Z, r->Y);
228 | fe_add(r->Y, r->Z, r->Y);
229 | fe_add(r->Z, t0, r->T);
230 | fe_sub(r->T, t0, r->T);
231 | }
232 |
233 | /*
234 | r = p - q
235 | */
236 |
237 | void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
238 | fe t0;
239 |
240 | fe_add(r->X, p->Y, p->X);
241 | fe_sub(r->Y, p->Y, p->X);
242 | fe_mul(r->Z, r->X, q->yminusx);
243 | fe_mul(r->Y, r->Y, q->yplusx);
244 | fe_mul(r->T, q->xy2d, p->T);
245 | fe_add(t0, p->Z, p->Z);
246 | fe_sub(r->X, r->Z, r->Y);
247 | fe_add(r->Y, r->Z, r->Y);
248 | fe_sub(r->Z, t0, r->T);
249 | fe_add(r->T, t0, r->T);
250 | }
251 |
252 | /*
253 | r = p
254 | */
255 |
256 | void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
257 | fe_mul(r->X, p->X, p->T);
258 | fe_mul(r->Y, p->Y, p->Z);
259 | fe_mul(r->Z, p->Z, p->T);
260 | }
261 |
262 | /*
263 | r = p
264 | */
265 |
266 | void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
267 | fe_mul(r->X, p->X, p->T);
268 | fe_mul(r->Y, p->Y, p->Z);
269 | fe_mul(r->Z, p->Z, p->T);
270 | fe_mul(r->T, p->X, p->Y);
271 | }
272 |
273 | void ge_p2_0(ge_p2 *h) {
274 | fe_0(h->X);
275 | fe_1(h->Y);
276 | fe_1(h->Z);
277 | }
278 |
279 | /*
280 | r = 2 * p
281 | */
282 |
283 | void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
284 | fe t0;
285 |
286 | fe_sq(r->X, p->X);
287 | fe_sq(r->Z, p->Y);
288 | fe_sq2(r->T, p->Z);
289 | fe_add(r->Y, p->X, p->Y);
290 | fe_sq(t0, r->Y);
291 | fe_add(r->Y, r->Z, r->X);
292 | fe_sub(r->Z, r->Z, r->X);
293 | fe_sub(r->X, t0, r->Y);
294 | fe_sub(r->T, r->T, r->Z);
295 | }
296 |
297 | void ge_p3_0(ge_p3 *h) {
298 | fe_0(h->X);
299 | fe_1(h->Y);
300 | fe_1(h->Z);
301 | fe_0(h->T);
302 | }
303 |
304 | /*
305 | r = 2 * p
306 | */
307 |
308 | void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
309 | ge_p2 q;
310 | ge_p3_to_p2(&q, p);
311 | ge_p2_dbl(r, &q);
312 | }
313 |
314 | /*
315 | r = p
316 | */
317 |
318 | static const fe d2 = {
319 | -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199
320 | };
321 |
322 | void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
323 | fe_add(r->YplusX, p->Y, p->X);
324 | fe_sub(r->YminusX, p->Y, p->X);
325 | fe_copy(r->Z, p->Z);
326 | fe_mul(r->T2d, p->T, d2);
327 | }
328 |
329 | /*
330 | r = p
331 | */
332 |
333 | void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
334 | fe_copy(r->X, p->X);
335 | fe_copy(r->Y, p->Y);
336 | fe_copy(r->Z, p->Z);
337 | }
338 |
339 | void ge_p3_tobytes(uint8_t *s, const ge_p3 *h) {
340 | fe recip;
341 | fe x;
342 | fe y;
343 | fe_invert(recip, h->Z);
344 | fe_mul(x, h->X, recip);
345 | fe_mul(y, h->Y, recip);
346 | fe_tobytes(s, y);
347 | s[31] ^= fe_isnegative(x) << 7;
348 | }
349 |
350 | static uint8_t equal(int8_t b, int8_t c) {
351 | uint8_t ub = b;
352 | uint8_t uc = c;
353 | uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */
354 | uint64_t y = x; /* 0: yes; 1..255: no */
355 | y -= 1; /* large: yes; 0..254: no */
356 | y >>= 63; /* 1: yes; 0: no */
357 | return (uint8_t)y;
358 | }
359 |
360 | static uint8_t negative(int8_t b) {
361 | uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
362 | x >>= 63; /* 1: yes; 0: no */
363 | return (uint8_t)x;
364 | }
365 |
366 | static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) {
367 | fe_cmov(t->yplusx, u->yplusx, b);
368 | fe_cmov(t->yminusx, u->yminusx, b);
369 | fe_cmov(t->xy2d, u->xy2d, b);
370 | }
371 |
372 | static void select(ge_precomp *t, int pos, int8_t b) {
373 | ge_precomp minust;
374 | uint8_t bnegative = negative(b);
375 | uint8_t babs = b - (((-bnegative) & b) << 1);
376 | fe_1(t->yplusx);
377 | fe_1(t->yminusx);
378 | fe_0(t->xy2d);
379 | cmov(t, &base[pos][0], equal(babs, 1));
380 | cmov(t, &base[pos][1], equal(babs, 2));
381 | cmov(t, &base[pos][2], equal(babs, 3));
382 | cmov(t, &base[pos][3], equal(babs, 4));
383 | cmov(t, &base[pos][4], equal(babs, 5));
384 | cmov(t, &base[pos][5], equal(babs, 6));
385 | cmov(t, &base[pos][6], equal(babs, 7));
386 | cmov(t, &base[pos][7], equal(babs, 8));
387 | fe_copy(minust.yplusx, t->yminusx);
388 | fe_copy(minust.yminusx, t->yplusx);
389 | fe_neg(minust.xy2d, t->xy2d);
390 | cmov(t, &minust, bnegative);
391 | }
392 |
393 | /*
394 | h = a * B
395 | where a = a[0]+256*a[1]+...+256^31 a[31]
396 | B is the Ed25519 base point (x,4/5) with x positive.
397 |
398 | Preconditions:
399 | a[31] <= 127
400 | */
401 |
402 | void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
403 | int8_t e[64];
404 | int8_t carry;
405 | ge_p1p1 r;
406 | ge_p2 s;
407 | ge_precomp t;
408 | int i;
409 |
410 | for (i = 0; i < 32; ++i) {
411 | e[2 * i + 0] = (a[i] >> 0) & 15;
412 | e[2 * i + 1] = (a[i] >> 4) & 15;
413 | }
414 |
415 | /* each e[i] is between 0 and 15 */
416 | /* e[63] is between 0 and 7 */
417 | carry = 0;
418 |
419 | for (i = 0; i < 63; ++i) {
420 | e[i] += carry;
421 | carry = e[i] + 8;
422 | carry >>= 4;
423 | e[i] -= carry << 4;
424 | }
425 |
426 | e[63] += carry;
427 | /* each e[i] is between -8 and 8 */
428 | ge_p3_0(h);
429 |
430 | for (i = 1; i < 64; i += 2) {
431 | select(&t, i / 2, e[i]);
432 | ge_madd(&r, h, &t);
433 | ge_p1p1_to_p3(h, &r);
434 | }
435 |
436 | ge_p3_dbl(&r, h);
437 | ge_p1p1_to_p2(&s, &r);
438 | ge_p2_dbl(&r, &s);
439 | ge_p1p1_to_p2(&s, &r);
440 | ge_p2_dbl(&r, &s);
441 | ge_p1p1_to_p2(&s, &r);
442 | ge_p2_dbl(&r, &s);
443 | ge_p1p1_to_p3(h, &r);
444 |
445 | for (i = 0; i < 64; i += 2) {
446 | select(&t, i / 2, e[i]);
447 | ge_madd(&r, h, &t);
448 | ge_p1p1_to_p3(h, &r);
449 | }
450 | }
451 |
452 | /*
453 | r = p - q
454 | */
455 |
456 | void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
457 | fe t0;
458 |
459 | fe_add(r->X, p->Y, p->X);
460 | fe_sub(r->Y, p->Y, p->X);
461 | fe_mul(r->Z, r->X, q->YminusX);
462 | fe_mul(r->Y, r->Y, q->YplusX);
463 | fe_mul(r->T, q->T2d, p->T);
464 | fe_mul(r->X, p->Z, q->Z);
465 | fe_add(t0, r->X, r->X);
466 | fe_sub(r->X, r->Z, r->Y);
467 | fe_add(r->Y, r->Z, r->Y);
468 | fe_sub(r->Z, t0, r->T);
469 | fe_add(r->T, t0, r->T);
470 | }
471 |
472 | void ge_tobytes(uint8_t *s, const ge_p2 *h) {
473 | fe recip;
474 | fe x;
475 | fe y;
476 | fe_invert(recip, h->Z);
477 | fe_mul(x, h->X, recip);
478 | fe_mul(y, h->Y, recip);
479 | fe_tobytes(s, y);
480 | s[31] ^= fe_isnegative(x) << 7;
481 | }
482 |
--------------------------------------------------------------------------------
/ed25519_ref10/ed25519_sc.cpp:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* ed25519_sc.cpp */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | /* This file was derived from information found at */
32 | /* https://tools.ietf.org/html/rfc8032#page-44 */
33 |
34 | #include "ed25519_sc.h"
35 |
36 | static uint64_t load_3(const uint8_t *in) {
37 | uint64_t result;
38 |
39 | result = (uint64_t)in[0];
40 | result |= ((uint64_t)in[1]) << 8;
41 | result |= ((uint64_t)in[2]) << 16;
42 |
43 | return result;
44 | }
45 |
46 | static uint64_t load_4(const uint8_t *in) {
47 | uint64_t result;
48 |
49 | result = (uint64_t)in[0];
50 | result |= ((uint64_t)in[1]) << 8;
51 | result |= ((uint64_t)in[2]) << 16;
52 | result |= ((uint64_t)in[3]) << 24;
53 |
54 | return result;
55 | }
56 |
57 | /*
58 | Input:
59 | s[0]+256*s[1]+...+256^63*s[63] = s
60 |
61 | Output:
62 | s[0]+256*s[1]+...+256^31*s[31] = s mod l
63 | where l = 2^252 + 27742317777372353535851937790883648493.
64 | Overwrites s in place.
65 | */
66 |
67 | void sc_reduce(uint8_t *s) {
68 | int64_t s0 = 2097151 & load_3(s);
69 | int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
70 | int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
71 | int64_t s3 = 2097151 & (load_4(s + 7) >> 7);
72 | int64_t s4 = 2097151 & (load_4(s + 10) >> 4);
73 | int64_t s5 = 2097151 & (load_3(s + 13) >> 1);
74 | int64_t s6 = 2097151 & (load_4(s + 15) >> 6);
75 | int64_t s7 = 2097151 & (load_3(s + 18) >> 3);
76 | int64_t s8 = 2097151 & load_3(s + 21);
77 | int64_t s9 = 2097151 & (load_4(s + 23) >> 5);
78 | int64_t s10 = 2097151 & (load_3(s + 26) >> 2);
79 | int64_t s11 = 2097151 & (load_4(s + 28) >> 7);
80 | int64_t s12 = 2097151 & (load_4(s + 31) >> 4);
81 | int64_t s13 = 2097151 & (load_3(s + 34) >> 1);
82 | int64_t s14 = 2097151 & (load_4(s + 36) >> 6);
83 | int64_t s15 = 2097151 & (load_3(s + 39) >> 3);
84 | int64_t s16 = 2097151 & load_3(s + 42);
85 | int64_t s17 = 2097151 & (load_4(s + 44) >> 5);
86 | int64_t s18 = 2097151 & (load_3(s + 47) >> 2);
87 | int64_t s19 = 2097151 & (load_4(s + 49) >> 7);
88 | int64_t s20 = 2097151 & (load_4(s + 52) >> 4);
89 | int64_t s21 = 2097151 & (load_3(s + 55) >> 1);
90 | int64_t s22 = 2097151 & (load_4(s + 57) >> 6);
91 | int64_t s23 = (load_4(s + 60) >> 3);
92 | int64_t carry0;
93 | int64_t carry1;
94 | int64_t carry2;
95 | int64_t carry3;
96 | int64_t carry4;
97 | int64_t carry5;
98 | int64_t carry6;
99 | int64_t carry7;
100 | int64_t carry8;
101 | int64_t carry9;
102 | int64_t carry10;
103 | int64_t carry11;
104 | int64_t carry12;
105 | int64_t carry13;
106 | int64_t carry14;
107 | int64_t carry15;
108 | int64_t carry16;
109 |
110 | s11 += s23 * 666643;
111 | s12 += s23 * 470296;
112 | s13 += s23 * 654183;
113 | s14 -= s23 * 997805;
114 | s15 += s23 * 136657;
115 | s16 -= s23 * 683901;
116 | s23 = 0;
117 | s10 += s22 * 666643;
118 | s11 += s22 * 470296;
119 | s12 += s22 * 654183;
120 | s13 -= s22 * 997805;
121 | s14 += s22 * 136657;
122 | s15 -= s22 * 683901;
123 | s22 = 0;
124 | s9 += s21 * 666643;
125 | s10 += s21 * 470296;
126 | s11 += s21 * 654183;
127 | s12 -= s21 * 997805;
128 | s13 += s21 * 136657;
129 | s14 -= s21 * 683901;
130 | s21 = 0;
131 | s8 += s20 * 666643;
132 | s9 += s20 * 470296;
133 | s10 += s20 * 654183;
134 | s11 -= s20 * 997805;
135 | s12 += s20 * 136657;
136 | s13 -= s20 * 683901;
137 | s20 = 0;
138 | s7 += s19 * 666643;
139 | s8 += s19 * 470296;
140 | s9 += s19 * 654183;
141 | s10 -= s19 * 997805;
142 | s11 += s19 * 136657;
143 | s12 -= s19 * 683901;
144 | s19 = 0;
145 | s6 += s18 * 666643;
146 | s7 += s18 * 470296;
147 | s8 += s18 * 654183;
148 | s9 -= s18 * 997805;
149 | s10 += s18 * 136657;
150 | s11 -= s18 * 683901;
151 | s18 = 0;
152 | carry6 = (s6 + (1 << 20)) >> 21;
153 | s7 += carry6;
154 | s6 -= carry6 << 21;
155 | carry8 = (s8 + (1 << 20)) >> 21;
156 | s9 += carry8;
157 | s8 -= carry8 << 21;
158 | carry10 = (s10 + (1 << 20)) >> 21;
159 | s11 += carry10;
160 | s10 -= carry10 << 21;
161 | carry12 = (s12 + (1 << 20)) >> 21;
162 | s13 += carry12;
163 | s12 -= carry12 << 21;
164 | carry14 = (s14 + (1 << 20)) >> 21;
165 | s15 += carry14;
166 | s14 -= carry14 << 21;
167 | carry16 = (s16 + (1 << 20)) >> 21;
168 | s17 += carry16;
169 | s16 -= carry16 << 21;
170 | carry7 = (s7 + (1 << 20)) >> 21;
171 | s8 += carry7;
172 | s7 -= carry7 << 21;
173 | carry9 = (s9 + (1 << 20)) >> 21;
174 | s10 += carry9;
175 | s9 -= carry9 << 21;
176 | carry11 = (s11 + (1 << 20)) >> 21;
177 | s12 += carry11;
178 | s11 -= carry11 << 21;
179 | carry13 = (s13 + (1 << 20)) >> 21;
180 | s14 += carry13;
181 | s13 -= carry13 << 21;
182 | carry15 = (s15 + (1 << 20)) >> 21;
183 | s16 += carry15;
184 | s15 -= carry15 << 21;
185 | s5 += s17 * 666643;
186 | s6 += s17 * 470296;
187 | s7 += s17 * 654183;
188 | s8 -= s17 * 997805;
189 | s9 += s17 * 136657;
190 | s10 -= s17 * 683901;
191 | s17 = 0;
192 | s4 += s16 * 666643;
193 | s5 += s16 * 470296;
194 | s6 += s16 * 654183;
195 | s7 -= s16 * 997805;
196 | s8 += s16 * 136657;
197 | s9 -= s16 * 683901;
198 | s16 = 0;
199 | s3 += s15 * 666643;
200 | s4 += s15 * 470296;
201 | s5 += s15 * 654183;
202 | s6 -= s15 * 997805;
203 | s7 += s15 * 136657;
204 | s8 -= s15 * 683901;
205 | s15 = 0;
206 | s2 += s14 * 666643;
207 | s3 += s14 * 470296;
208 | s4 += s14 * 654183;
209 | s5 -= s14 * 997805;
210 | s6 += s14 * 136657;
211 | s7 -= s14 * 683901;
212 | s14 = 0;
213 | s1 += s13 * 666643;
214 | s2 += s13 * 470296;
215 | s3 += s13 * 654183;
216 | s4 -= s13 * 997805;
217 | s5 += s13 * 136657;
218 | s6 -= s13 * 683901;
219 | s13 = 0;
220 | s0 += s12 * 666643;
221 | s1 += s12 * 470296;
222 | s2 += s12 * 654183;
223 | s3 -= s12 * 997805;
224 | s4 += s12 * 136657;
225 | s5 -= s12 * 683901;
226 | s12 = 0;
227 | carry0 = (s0 + (1 << 20)) >> 21;
228 | s1 += carry0;
229 | s0 -= carry0 << 21;
230 | carry2 = (s2 + (1 << 20)) >> 21;
231 | s3 += carry2;
232 | s2 -= carry2 << 21;
233 | carry4 = (s4 + (1 << 20)) >> 21;
234 | s5 += carry4;
235 | s4 -= carry4 << 21;
236 | carry6 = (s6 + (1 << 20)) >> 21;
237 | s7 += carry6;
238 | s6 -= carry6 << 21;
239 | carry8 = (s8 + (1 << 20)) >> 21;
240 | s9 += carry8;
241 | s8 -= carry8 << 21;
242 | carry10 = (s10 + (1 << 20)) >> 21;
243 | s11 += carry10;
244 | s10 -= carry10 << 21;
245 | carry1 = (s1 + (1 << 20)) >> 21;
246 | s2 += carry1;
247 | s1 -= carry1 << 21;
248 | carry3 = (s3 + (1 << 20)) >> 21;
249 | s4 += carry3;
250 | s3 -= carry3 << 21;
251 | carry5 = (s5 + (1 << 20)) >> 21;
252 | s6 += carry5;
253 | s5 -= carry5 << 21;
254 | carry7 = (s7 + (1 << 20)) >> 21;
255 | s8 += carry7;
256 | s7 -= carry7 << 21;
257 | carry9 = (s9 + (1 << 20)) >> 21;
258 | s10 += carry9;
259 | s9 -= carry9 << 21;
260 | carry11 = (s11 + (1 << 20)) >> 21;
261 | s12 += carry11;
262 | s11 -= carry11 << 21;
263 | s0 += s12 * 666643;
264 | s1 += s12 * 470296;
265 | s2 += s12 * 654183;
266 | s3 -= s12 * 997805;
267 | s4 += s12 * 136657;
268 | s5 -= s12 * 683901;
269 | s12 = 0;
270 | carry0 = s0 >> 21;
271 | s1 += carry0;
272 | s0 -= carry0 << 21;
273 | carry1 = s1 >> 21;
274 | s2 += carry1;
275 | s1 -= carry1 << 21;
276 | carry2 = s2 >> 21;
277 | s3 += carry2;
278 | s2 -= carry2 << 21;
279 | carry3 = s3 >> 21;
280 | s4 += carry3;
281 | s3 -= carry3 << 21;
282 | carry4 = s4 >> 21;
283 | s5 += carry4;
284 | s4 -= carry4 << 21;
285 | carry5 = s5 >> 21;
286 | s6 += carry5;
287 | s5 -= carry5 << 21;
288 | carry6 = s6 >> 21;
289 | s7 += carry6;
290 | s6 -= carry6 << 21;
291 | carry7 = s7 >> 21;
292 | s8 += carry7;
293 | s7 -= carry7 << 21;
294 | carry8 = s8 >> 21;
295 | s9 += carry8;
296 | s8 -= carry8 << 21;
297 | carry9 = s9 >> 21;
298 | s10 += carry9;
299 | s9 -= carry9 << 21;
300 | carry10 = s10 >> 21;
301 | s11 += carry10;
302 | s10 -= carry10 << 21;
303 | carry11 = s11 >> 21;
304 | s12 += carry11;
305 | s11 -= carry11 << 21;
306 | s0 += s12 * 666643;
307 | s1 += s12 * 470296;
308 | s2 += s12 * 654183;
309 | s3 -= s12 * 997805;
310 | s4 += s12 * 136657;
311 | s5 -= s12 * 683901;
312 | s12 = 0;
313 | carry0 = s0 >> 21;
314 | s1 += carry0;
315 | s0 -= carry0 << 21;
316 | carry1 = s1 >> 21;
317 | s2 += carry1;
318 | s1 -= carry1 << 21;
319 | carry2 = s2 >> 21;
320 | s3 += carry2;
321 | s2 -= carry2 << 21;
322 | carry3 = s3 >> 21;
323 | s4 += carry3;
324 | s3 -= carry3 << 21;
325 | carry4 = s4 >> 21;
326 | s5 += carry4;
327 | s4 -= carry4 << 21;
328 | carry5 = s5 >> 21;
329 | s6 += carry5;
330 | s5 -= carry5 << 21;
331 | carry6 = s6 >> 21;
332 | s7 += carry6;
333 | s6 -= carry6 << 21;
334 | carry7 = s7 >> 21;
335 | s8 += carry7;
336 | s7 -= carry7 << 21;
337 | carry8 = s8 >> 21;
338 | s9 += carry8;
339 | s8 -= carry8 << 21;
340 | carry9 = s9 >> 21;
341 | s10 += carry9;
342 | s9 -= carry9 << 21;
343 | carry10 = s10 >> 21;
344 | s11 += carry10;
345 | s10 -= carry10 << 21;
346 |
347 | s[0] = (uint8_t)(s0 >> 0);
348 | s[1] = (uint8_t)(s0 >> 8);
349 | s[2] = (uint8_t)((s0 >> 16) | (s1 << 5));
350 | s[3] = (uint8_t)(s1 >> 3);
351 | s[4] = (uint8_t)(s1 >> 11);
352 | s[5] = (uint8_t)((s1 >> 19) | (s2 << 2));
353 | s[6] = (uint8_t)(s2 >> 6);
354 | s[7] = (uint8_t)((s2 >> 14) | (s3 << 7));
355 | s[8] = (uint8_t)(s3 >> 1);
356 | s[9] = (uint8_t)(s3 >> 9);
357 | s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
358 | s[11] = (uint8_t)(s4 >> 4);
359 | s[12] = (uint8_t)(s4 >> 12);
360 | s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
361 | s[14] = (uint8_t)(s5 >> 7);
362 | s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
363 | s[16] = (uint8_t)(s6 >> 2);
364 | s[17] = (uint8_t)(s6 >> 10);
365 | s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
366 | s[19] = (uint8_t)(s7 >> 5);
367 | s[20] = (uint8_t)(s7 >> 13);
368 | s[21] = (uint8_t)(s8 >> 0);
369 | s[22] = (uint8_t)(s8 >> 8);
370 | s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
371 | s[24] = (uint8_t)(s9 >> 3);
372 | s[25] = (uint8_t)(s9 >> 11);
373 | s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
374 | s[27] = (uint8_t)(s10 >> 6);
375 | s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
376 | s[29] = (uint8_t)(s11 >> 1);
377 | s[30] = (uint8_t)(s11 >> 9);
378 | s[31] = (uint8_t)(s11 >> 17);
379 | }
380 |
381 | /*
382 | Input:
383 | a[0]+256*a[1]+...+256^31*a[31] = a
384 | b[0]+256*b[1]+...+256^31*b[31] = b
385 | c[0]+256*c[1]+...+256^31*c[31] = c
386 |
387 | Output:
388 | s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
389 | where l = 2^252 + 27742317777372353535851937790883648493.
390 | */
391 |
392 | void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, const uint8_t *c) {
393 | int64_t a0 = 2097151 & load_3(a);
394 | int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
395 | int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
396 | int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
397 | int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
398 | int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
399 | int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
400 | int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
401 | int64_t a8 = 2097151 & load_3(a + 21);
402 | int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
403 | int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
404 | int64_t a11 = (load_4(a + 28) >> 7);
405 | int64_t b0 = 2097151 & load_3(b);
406 | int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
407 | int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
408 | int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
409 | int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
410 | int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
411 | int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
412 | int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
413 | int64_t b8 = 2097151 & load_3(b + 21);
414 | int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
415 | int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
416 | int64_t b11 = (load_4(b + 28) >> 7);
417 | int64_t c0 = 2097151 & load_3(c);
418 | int64_t c1 = 2097151 & (load_4(c + 2) >> 5);
419 | int64_t c2 = 2097151 & (load_3(c + 5) >> 2);
420 | int64_t c3 = 2097151 & (load_4(c + 7) >> 7);
421 | int64_t c4 = 2097151 & (load_4(c + 10) >> 4);
422 | int64_t c5 = 2097151 & (load_3(c + 13) >> 1);
423 | int64_t c6 = 2097151 & (load_4(c + 15) >> 6);
424 | int64_t c7 = 2097151 & (load_3(c + 18) >> 3);
425 | int64_t c8 = 2097151 & load_3(c + 21);
426 | int64_t c9 = 2097151 & (load_4(c + 23) >> 5);
427 | int64_t c10 = 2097151 & (load_3(c + 26) >> 2);
428 | int64_t c11 = (load_4(c + 28) >> 7);
429 | int64_t s0;
430 | int64_t s1;
431 | int64_t s2;
432 | int64_t s3;
433 | int64_t s4;
434 | int64_t s5;
435 | int64_t s6;
436 | int64_t s7;
437 | int64_t s8;
438 | int64_t s9;
439 | int64_t s10;
440 | int64_t s11;
441 | int64_t s12;
442 | int64_t s13;
443 | int64_t s14;
444 | int64_t s15;
445 | int64_t s16;
446 | int64_t s17;
447 | int64_t s18;
448 | int64_t s19;
449 | int64_t s20;
450 | int64_t s21;
451 | int64_t s22;
452 | int64_t s23;
453 | int64_t carry0;
454 | int64_t carry1;
455 | int64_t carry2;
456 | int64_t carry3;
457 | int64_t carry4;
458 | int64_t carry5;
459 | int64_t carry6;
460 | int64_t carry7;
461 | int64_t carry8;
462 | int64_t carry9;
463 | int64_t carry10;
464 | int64_t carry11;
465 | int64_t carry12;
466 | int64_t carry13;
467 | int64_t carry14;
468 | int64_t carry15;
469 | int64_t carry16;
470 | int64_t carry17;
471 | int64_t carry18;
472 | int64_t carry19;
473 | int64_t carry20;
474 | int64_t carry21;
475 | int64_t carry22;
476 |
477 | s0 = c0 + a0 * b0;
478 | s1 = c1 + a0 * b1 + a1 * b0;
479 | s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
480 | s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
481 | s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
482 | s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
483 | s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
484 | s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0;
485 | s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0;
486 | s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
487 | s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
488 | s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
489 | s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
490 | s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2;
491 | s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3;
492 | s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4;
493 | s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
494 | s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
495 | s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
496 | s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
497 | s20 = a9 * b11 + a10 * b10 + a11 * b9;
498 | s21 = a10 * b11 + a11 * b10;
499 | s22 = a11 * b11;
500 | s23 = 0;
501 | carry0 = (s0 + (1 << 20)) >> 21;
502 | s1 += carry0;
503 | s0 -= carry0 << 21;
504 | carry2 = (s2 + (1 << 20)) >> 21;
505 | s3 += carry2;
506 | s2 -= carry2 << 21;
507 | carry4 = (s4 + (1 << 20)) >> 21;
508 | s5 += carry4;
509 | s4 -= carry4 << 21;
510 | carry6 = (s6 + (1 << 20)) >> 21;
511 | s7 += carry6;
512 | s6 -= carry6 << 21;
513 | carry8 = (s8 + (1 << 20)) >> 21;
514 | s9 += carry8;
515 | s8 -= carry8 << 21;
516 | carry10 = (s10 + (1 << 20)) >> 21;
517 | s11 += carry10;
518 | s10 -= carry10 << 21;
519 | carry12 = (s12 + (1 << 20)) >> 21;
520 | s13 += carry12;
521 | s12 -= carry12 << 21;
522 | carry14 = (s14 + (1 << 20)) >> 21;
523 | s15 += carry14;
524 | s14 -= carry14 << 21;
525 | carry16 = (s16 + (1 << 20)) >> 21;
526 | s17 += carry16;
527 | s16 -= carry16 << 21;
528 | carry18 = (s18 + (1 << 20)) >> 21;
529 | s19 += carry18;
530 | s18 -= carry18 << 21;
531 | carry20 = (s20 + (1 << 20)) >> 21;
532 | s21 += carry20;
533 | s20 -= carry20 << 21;
534 | carry22 = (s22 + (1 << 20)) >> 21;
535 | s23 += carry22;
536 | s22 -= carry22 << 21;
537 | carry1 = (s1 + (1 << 20)) >> 21;
538 | s2 += carry1;
539 | s1 -= carry1 << 21;
540 | carry3 = (s3 + (1 << 20)) >> 21;
541 | s4 += carry3;
542 | s3 -= carry3 << 21;
543 | carry5 = (s5 + (1 << 20)) >> 21;
544 | s6 += carry5;
545 | s5 -= carry5 << 21;
546 | carry7 = (s7 + (1 << 20)) >> 21;
547 | s8 += carry7;
548 | s7 -= carry7 << 21;
549 | carry9 = (s9 + (1 << 20)) >> 21;
550 | s10 += carry9;
551 | s9 -= carry9 << 21;
552 | carry11 = (s11 + (1 << 20)) >> 21;
553 | s12 += carry11;
554 | s11 -= carry11 << 21;
555 | carry13 = (s13 + (1 << 20)) >> 21;
556 | s14 += carry13;
557 | s13 -= carry13 << 21;
558 | carry15 = (s15 + (1 << 20)) >> 21;
559 | s16 += carry15;
560 | s15 -= carry15 << 21;
561 | carry17 = (s17 + (1 << 20)) >> 21;
562 | s18 += carry17;
563 | s17 -= carry17 << 21;
564 | carry19 = (s19 + (1 << 20)) >> 21;
565 | s20 += carry19;
566 | s19 -= carry19 << 21;
567 | carry21 = (s21 + (1 << 20)) >> 21;
568 | s22 += carry21;
569 | s21 -= carry21 << 21;
570 | s11 += s23 * 666643;
571 | s12 += s23 * 470296;
572 | s13 += s23 * 654183;
573 | s14 -= s23 * 997805;
574 | s15 += s23 * 136657;
575 | s16 -= s23 * 683901;
576 | s23 = 0;
577 | s10 += s22 * 666643;
578 | s11 += s22 * 470296;
579 | s12 += s22 * 654183;
580 | s13 -= s22 * 997805;
581 | s14 += s22 * 136657;
582 | s15 -= s22 * 683901;
583 | s22 = 0;
584 | s9 += s21 * 666643;
585 | s10 += s21 * 470296;
586 | s11 += s21 * 654183;
587 | s12 -= s21 * 997805;
588 | s13 += s21 * 136657;
589 | s14 -= s21 * 683901;
590 | s21 = 0;
591 | s8 += s20 * 666643;
592 | s9 += s20 * 470296;
593 | s10 += s20 * 654183;
594 | s11 -= s20 * 997805;
595 | s12 += s20 * 136657;
596 | s13 -= s20 * 683901;
597 | s20 = 0;
598 | s7 += s19 * 666643;
599 | s8 += s19 * 470296;
600 | s9 += s19 * 654183;
601 | s10 -= s19 * 997805;
602 | s11 += s19 * 136657;
603 | s12 -= s19 * 683901;
604 | s19 = 0;
605 | s6 += s18 * 666643;
606 | s7 += s18 * 470296;
607 | s8 += s18 * 654183;
608 | s9 -= s18 * 997805;
609 | s10 += s18 * 136657;
610 | s11 -= s18 * 683901;
611 | s18 = 0;
612 | carry6 = (s6 + (1 << 20)) >> 21;
613 | s7 += carry6;
614 | s6 -= carry6 << 21;
615 | carry8 = (s8 + (1 << 20)) >> 21;
616 | s9 += carry8;
617 | s8 -= carry8 << 21;
618 | carry10 = (s10 + (1 << 20)) >> 21;
619 | s11 += carry10;
620 | s10 -= carry10 << 21;
621 | carry12 = (s12 + (1 << 20)) >> 21;
622 | s13 += carry12;
623 | s12 -= carry12 << 21;
624 | carry14 = (s14 + (1 << 20)) >> 21;
625 | s15 += carry14;
626 | s14 -= carry14 << 21;
627 | carry16 = (s16 + (1 << 20)) >> 21;
628 | s17 += carry16;
629 | s16 -= carry16 << 21;
630 | carry7 = (s7 + (1 << 20)) >> 21;
631 | s8 += carry7;
632 | s7 -= carry7 << 21;
633 | carry9 = (s9 + (1 << 20)) >> 21;
634 | s10 += carry9;
635 | s9 -= carry9 << 21;
636 | carry11 = (s11 + (1 << 20)) >> 21;
637 | s12 += carry11;
638 | s11 -= carry11 << 21;
639 | carry13 = (s13 + (1 << 20)) >> 21;
640 | s14 += carry13;
641 | s13 -= carry13 << 21;
642 | carry15 = (s15 + (1 << 20)) >> 21;
643 | s16 += carry15;
644 | s15 -= carry15 << 21;
645 | s5 += s17 * 666643;
646 | s6 += s17 * 470296;
647 | s7 += s17 * 654183;
648 | s8 -= s17 * 997805;
649 | s9 += s17 * 136657;
650 | s10 -= s17 * 683901;
651 | s17 = 0;
652 | s4 += s16 * 666643;
653 | s5 += s16 * 470296;
654 | s6 += s16 * 654183;
655 | s7 -= s16 * 997805;
656 | s8 += s16 * 136657;
657 | s9 -= s16 * 683901;
658 | s16 = 0;
659 | s3 += s15 * 666643;
660 | s4 += s15 * 470296;
661 | s5 += s15 * 654183;
662 | s6 -= s15 * 997805;
663 | s7 += s15 * 136657;
664 | s8 -= s15 * 683901;
665 | s15 = 0;
666 | s2 += s14 * 666643;
667 | s3 += s14 * 470296;
668 | s4 += s14 * 654183;
669 | s5 -= s14 * 997805;
670 | s6 += s14 * 136657;
671 | s7 -= s14 * 683901;
672 | s14 = 0;
673 | s1 += s13 * 666643;
674 | s2 += s13 * 470296;
675 | s3 += s13 * 654183;
676 | s4 -= s13 * 997805;
677 | s5 += s13 * 136657;
678 | s6 -= s13 * 683901;
679 | s13 = 0;
680 | s0 += s12 * 666643;
681 | s1 += s12 * 470296;
682 | s2 += s12 * 654183;
683 | s3 -= s12 * 997805;
684 | s4 += s12 * 136657;
685 | s5 -= s12 * 683901;
686 | s12 = 0;
687 | carry0 = (s0 + (1 << 20)) >> 21;
688 | s1 += carry0;
689 | s0 -= carry0 << 21;
690 | carry2 = (s2 + (1 << 20)) >> 21;
691 | s3 += carry2;
692 | s2 -= carry2 << 21;
693 | carry4 = (s4 + (1 << 20)) >> 21;
694 | s5 += carry4;
695 | s4 -= carry4 << 21;
696 | carry6 = (s6 + (1 << 20)) >> 21;
697 | s7 += carry6;
698 | s6 -= carry6 << 21;
699 | carry8 = (s8 + (1 << 20)) >> 21;
700 | s9 += carry8;
701 | s8 -= carry8 << 21;
702 | carry10 = (s10 + (1 << 20)) >> 21;
703 | s11 += carry10;
704 | s10 -= carry10 << 21;
705 | carry1 = (s1 + (1 << 20)) >> 21;
706 | s2 += carry1;
707 | s1 -= carry1 << 21;
708 | carry3 = (s3 + (1 << 20)) >> 21;
709 | s4 += carry3;
710 | s3 -= carry3 << 21;
711 | carry5 = (s5 + (1 << 20)) >> 21;
712 | s6 += carry5;
713 | s5 -= carry5 << 21;
714 | carry7 = (s7 + (1 << 20)) >> 21;
715 | s8 += carry7;
716 | s7 -= carry7 << 21;
717 | carry9 = (s9 + (1 << 20)) >> 21;
718 | s10 += carry9;
719 | s9 -= carry9 << 21;
720 | carry11 = (s11 + (1 << 20)) >> 21;
721 | s12 += carry11;
722 | s11 -= carry11 << 21;
723 | s0 += s12 * 666643;
724 | s1 += s12 * 470296;
725 | s2 += s12 * 654183;
726 | s3 -= s12 * 997805;
727 | s4 += s12 * 136657;
728 | s5 -= s12 * 683901;
729 | s12 = 0;
730 | carry0 = s0 >> 21;
731 | s1 += carry0;
732 | s0 -= carry0 << 21;
733 | carry1 = s1 >> 21;
734 | s2 += carry1;
735 | s1 -= carry1 << 21;
736 | carry2 = s2 >> 21;
737 | s3 += carry2;
738 | s2 -= carry2 << 21;
739 | carry3 = s3 >> 21;
740 | s4 += carry3;
741 | s3 -= carry3 << 21;
742 | carry4 = s4 >> 21;
743 | s5 += carry4;
744 | s4 -= carry4 << 21;
745 | carry5 = s5 >> 21;
746 | s6 += carry5;
747 | s5 -= carry5 << 21;
748 | carry6 = s6 >> 21;
749 | s7 += carry6;
750 | s6 -= carry6 << 21;
751 | carry7 = s7 >> 21;
752 | s8 += carry7;
753 | s7 -= carry7 << 21;
754 | carry8 = s8 >> 21;
755 | s9 += carry8;
756 | s8 -= carry8 << 21;
757 | carry9 = s9 >> 21;
758 | s10 += carry9;
759 | s9 -= carry9 << 21;
760 | carry10 = s10 >> 21;
761 | s11 += carry10;
762 | s10 -= carry10 << 21;
763 | carry11 = s11 >> 21;
764 | s12 += carry11;
765 | s11 -= carry11 << 21;
766 | s0 += s12 * 666643;
767 | s1 += s12 * 470296;
768 | s2 += s12 * 654183;
769 | s3 -= s12 * 997805;
770 | s4 += s12 * 136657;
771 | s5 -= s12 * 683901;
772 | s12 = 0;
773 | carry0 = s0 >> 21;
774 | s1 += carry0;
775 | s0 -= carry0 << 21;
776 | carry1 = s1 >> 21;
777 | s2 += carry1;
778 | s1 -= carry1 << 21;
779 | carry2 = s2 >> 21;
780 | s3 += carry2;
781 | s2 -= carry2 << 21;
782 | carry3 = s3 >> 21;
783 | s4 += carry3;
784 | s3 -= carry3 << 21;
785 | carry4 = s4 >> 21;
786 | s5 += carry4;
787 | s4 -= carry4 << 21;
788 | carry5 = s5 >> 21;
789 | s6 += carry5;
790 | s5 -= carry5 << 21;
791 | carry6 = s6 >> 21;
792 | s7 += carry6;
793 | s6 -= carry6 << 21;
794 | carry7 = s7 >> 21;
795 | s8 += carry7;
796 | s7 -= carry7 << 21;
797 | carry8 = s8 >> 21;
798 | s9 += carry8;
799 | s8 -= carry8 << 21;
800 | carry9 = s9 >> 21;
801 | s10 += carry9;
802 | s9 -= carry9 << 21;
803 | carry10 = s10 >> 21;
804 | s11 += carry10;
805 | s10 -= carry10 << 21;
806 |
807 | s[0] = (uint8_t)(s0 >> 0);
808 | s[1] = (uint8_t)(s0 >> 8);
809 | s[2] = (uint8_t)((s0 >> 16) | (s1 << 5));
810 | s[3] = (uint8_t)(s1 >> 3);
811 | s[4] = (uint8_t)(s1 >> 11);
812 | s[5] = (uint8_t)((s1 >> 19) | (s2 << 2));
813 | s[6] = (uint8_t)(s2 >> 6);
814 | s[7] = (uint8_t)((s2 >> 14) | (s3 << 7));
815 | s[8] = (uint8_t)(s3 >> 1);
816 | s[9] = (uint8_t)(s3 >> 9);
817 | s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
818 | s[11] = (uint8_t)(s4 >> 4);
819 | s[12] = (uint8_t)(s4 >> 12);
820 | s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
821 | s[14] = (uint8_t)(s5 >> 7);
822 | s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
823 | s[16] = (uint8_t)(s6 >> 2);
824 | s[17] = (uint8_t)(s6 >> 10);
825 | s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
826 | s[19] = (uint8_t)(s7 >> 5);
827 | s[20] = (uint8_t)(s7 >> 13);
828 | s[21] = (uint8_t)(s8 >> 0);
829 | s[22] = (uint8_t)(s8 >> 8);
830 | s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
831 | s[24] = (uint8_t)(s9 >> 3);
832 | s[25] = (uint8_t)(s9 >> 11);
833 | s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
834 | s[27] = (uint8_t)(s10 >> 6);
835 | s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
836 | s[29] = (uint8_t)(s11 >> 1);
837 | s[30] = (uint8_t)(s11 >> 9);
838 | s[31] = (uint8_t)(s11 >> 17);
839 | }
840 |
--------------------------------------------------------------------------------
/mariadb.cpp:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* mariadb.cpp */
3 | /*************************************************************************/
4 | /* This file is part of: */
5 | /* GODOT ENGINE */
6 | /* https://godotengine.org */
7 | /*************************************************************************/
8 | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
9 | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
10 | /* */
11 | /* Permission is hereby granted, free of charge, to any person obtaining */
12 | /* a copy of this software and associated documentation files (the */
13 | /* "Software"), to deal in the Software without restriction, including */
14 | /* without limitation the rights to use, copy, modify, merge, publish, */
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */
16 | /* permit persons to whom the Software is furnished to do so, subject to */
17 | /* the following conditions: */
18 | /* */
19 | /* The above copyright notice and this permission notice shall be */
20 | /* included in all copies or substantial portions of the Software. */
21 | /* */
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 | /*************************************************************************/
30 |
31 | #include "mariadb.h"
32 |
33 | #include "mariadb_auth.h"
34 | //#include "utils/console.h" //removed for iostream removal
35 | #include "mariadb_conversions.h"
36 | //#include "utils/print_funcs.h"
37 |
38 | #include //for std::cout Using ERR_FAIL_COND_MSG(false, msg)
39 | //#include
40 | //#include //remove for Godot usage guidelines no stl
41 | //#include //remove for Godot usage guidelines no stl
42 | //#include //remove for Godot usage guidelines no stl
43 |
44 | #include "core/os/memory.h"
45 | #include "core/variant/variant.h"
46 | #include
47 |
48 | MariaDB::MariaDB() {
49 | }
50 |
51 | MariaDB::~MariaDB() {
52 | disconnect_db();
53 | // _tcp_polling = false;
54 | // _running = false;
55 |
56 | // if (_tcp_thread.is_started())
57 | // _tcp_thread.wait_to_finish();
58 | }
59 |
60 | //Bind all your methods used in this class
61 | void MariaDB::_bind_methods() {
62 | ClassDB::bind_method(D_METHOD("connect_db", "hostname", "port", "database", "username", "password", "authtype",
63 | "is_prehashed"),
64 | &MariaDB::connect_db, DEFVAL(AUTH_TYPE_ED25519), DEFVAL(true));
65 | ClassDB::bind_method(D_METHOD("disconnect_db"), &MariaDB::disconnect_db);
66 | ClassDB::bind_method(D_METHOD("get_last_query"), &MariaDB::get_last_query);
67 | ClassDB::bind_method(D_METHOD("get_last_query_converted"), &MariaDB::get_last_query_converted);
68 | ClassDB::bind_method(D_METHOD("get_last_response"), &MariaDB::get_last_response);
69 | ClassDB::bind_method(D_METHOD("get_last_transmitted"), &MariaDB::get_last_transmitted);
70 | ClassDB::bind_method(D_METHOD("is_connected_db"), &MariaDB::is_connected_db);
71 | ClassDB::bind_method(D_METHOD("set_dbl_to_string", "is_to_str"), &MariaDB::set_dbl_to_string);
72 | ClassDB::bind_method(D_METHOD("set_db_name", "db_name"), &MariaDB::set_db_name);
73 | ClassDB::bind_method(D_METHOD("query", "sql_stmt"), &MariaDB::query);
74 |
75 | BIND_ENUM_CONSTANT(IP_TYPE_IPV4);
76 | BIND_ENUM_CONSTANT(IP_TYPE_IPV6);
77 | BIND_ENUM_CONSTANT(IP_TYPE_ANY);
78 |
79 | BIND_ENUM_CONSTANT(AUTH_TYPE_MYSQL_NATIVE);
80 | BIND_ENUM_CONSTANT(AUTH_TYPE_ED25519);
81 | }
82 |
83 | //Custom Functions
84 | //private
85 | void MariaDB::m_add_packet_header(Vector &p_pkt, uint8_t p_pkt_seq) {
86 | Vector t = little_endian_to_vbytes(p_pkt.size(), 3);
87 | t.push_back(p_pkt_seq);
88 | t.append_array(p_pkt);
89 | p_pkt = t.duplicate();
90 | }
91 |
92 | // void MariaDB::m_append_thread_data(PackedByteArray &p_data, const uint64_t p_timeout) {
93 | // int sz = 0;
94 | // uint64_t start = OS::get_singleton()->get_ticks_msec();
95 | // while (sz == 0 && OS::get_singleton()->get_ticks_msec() - start <= p_timeout) {
96 | // _tcp_mutex.lock();
97 | // sz = _tcp_thread_data.size();
98 | // if (sz > 0) {
99 | // p_data.append_array(_tcp_thread_data);
100 | // _tcp_thread_data.clear();
101 | // }
102 | // _tcp_mutex.unlock();
103 | // if (sz == 0) {
104 | // OS::get_singleton()->delay_usec(1000);
105 | // }
106 | // }
107 | // }
108 |
109 | uint32_t MariaDB::m_chk_rcv_bfr(Vector &p_bfr, int &p_bfr_size, const size_t p_cur_pos, const size_t p_need) {
110 | if (p_bfr_size - p_cur_pos < p_need)
111 | // m_append_thread_data(p_bfr);
112 | p_bfr.append_array(m_recv_data(1000));
113 |
114 | p_bfr_size = p_bfr.size();
115 | if (p_bfr_size - p_cur_pos < p_need) {
116 | return (uint32_t)ERR_PACKET_LENGTH_MISMATCH;
117 | } else {
118 | return (uint32_t)OK;
119 | }
120 | }
121 |
122 | //client protocol 4.1
123 | Error MariaDB::m_client_protocol_v41(const AuthType p_srvr_auth_type, const Vector p_srvr_salt) {
124 | Vector srvr_response;
125 | Vector srvr_auth_msg;
126 | uint8_t seq_num = 0;
127 | AuthType user_auth_type = AUTH_TYPE_ED25519;
128 |
129 | //Per https://mariadb.com/kb/en/connection/#handshake-response-packet
130 | //int<4> client capabilities
131 | _client_capabilities = 0;
132 | _client_capabilities |= (_server_capabilities & (uint64_t)Capabilities::CLIENT_MYSQL);
133 | //client_capabilities |= (uint64_t)Capabilities::FOUND_ROWS;
134 | _client_capabilities |= (uint64_t)Capabilities::LONG_FLAG; //??
135 | _client_capabilities |= (_server_capabilities & (uint64_t)Capabilities::CONNECT_WITH_DB);
136 | _client_capabilities |= (uint64_t)Capabilities::LOCAL_FILES;
137 | _client_capabilities |= (uint64_t)Capabilities::CLIENT_PROTOCOL_41;
138 | _client_capabilities |= (uint64_t)Capabilities::CLIENT_INTERACTIVE;
139 | _client_capabilities |= (uint64_t)Capabilities::SECURE_CONNECTION;
140 |
141 | // Not listed in MariaDB docs but if not set it won't parse the stream correctly
142 | _client_capabilities |= (uint64_t)Capabilities::RESERVED2;
143 |
144 | _client_capabilities |= (uint64_t)Capabilities::MULTI_STATEMENTS;
145 | _client_capabilities |= (uint64_t)Capabilities::MULTI_RESULTS;
146 | _client_capabilities |= (uint64_t)Capabilities::PS_MULTI_RESULTS;
147 | _client_capabilities |= (uint64_t)Capabilities::PLUGIN_AUTH;
148 |
149 | // Don't think this is needed for game dev needs, maybe for prepared statements?
150 | // _client_capabilities |= (_server_capabilities & (uint64_t)Capabilities::CLIENT_SEND_CONNECT_ATTRS);
151 |
152 | _client_capabilities |= (uint64_t)Capabilities::CAN_HANDLE_EXPIRED_PASSWORDS; //??
153 | _client_capabilities |= (uint64_t)Capabilities::SESSION_TRACK;
154 | _client_capabilities |= (_server_capabilities & (uint64_t)Capabilities::CLIENT_DEPRECATE_EOF);
155 | _client_capabilities |= (uint64_t)Capabilities::REMEMBER_OPTIONS; //??
156 |
157 | // Only send the first 4 bytes(32 bits) of capabilities the remaining will be sent later in another 4 byte
158 | Vector send_buffer_vec = little_endian_to_vbytes(_client_capabilities, 4);
159 |
160 | // int<4> max packet size
161 | // temp_vec = little_endian_bytes((uint32_t)0x40000000, 4);
162 | // send_buffer_vec.insert(send_buffer_vec.end(), temp_vec.begin(), temp_vec.end());
163 | send_buffer_vec.append_array(little_endian_to_vbytes((uint32_t)0x40000000, 4));
164 |
165 | // int<1> client character collation
166 | send_buffer_vec.push_back(33); //utf8_general_ci
167 |
168 | // string<19> reserved
169 | // send_buffer_vec.insert(send_buffer_vec.end(), 19, 0);
170 | Vector temp_vec;
171 | temp_vec.resize_zeroed(19);
172 | send_buffer_vec.append_array(temp_vec);
173 |
174 | if (!(_server_capabilities & (uint64_t)Capabilities::CLIENT_MYSQL) && _srvr_major_ver >= 10 &&
175 | _srvr_minor_ver >= 2) {
176 | // TODO implement Extended capabilities, if needed, this will result in more data between
177 | // _client_capabilities |= (_server_capabilities & (uint64_t)Capabilities::MARIADB_CLIENT_PROGRESS);
178 | // _client_capabilities |= (_server_capabilities & (uint64_t)Capabilities::MARIADB_CLIENT_COM_MULTI);
179 | // _client_capabilities |= (_server_capabilities & (uint64_t)Capabilities::MARIADB_CLIENT_STMT_BULK_OPERATIONS);
180 | // _client_capabilities |= (_server_capabilities & (uint64_t)Capabilities::MARIADB_CLIENT_EXTENDED_TYPE_INFO);
181 |
182 | // we need the metadata in the stream so we can form the dictionary ??
183 | _client_capabilities |= (_server_capabilities & (uint64_t)Capabilities::MARIADB_CLIENT_CACHE_METADATA);
184 | // int<4> extended client capabilities
185 | temp_vec = little_endian_to_vbytes(_client_capabilities, 4, 4);
186 | send_buffer_vec.append_array(temp_vec);
187 | } else {
188 | // string<4> reserved
189 | temp_vec.resize_zeroed(4);
190 | send_buffer_vec.append_array(temp_vec);
191 | }
192 |
193 | // string username
194 | //send_buffer_vec.insert(send_buffer_vec.end(), _username.begin(), _username.end());
195 | send_buffer_vec.append_array(_username);
196 | send_buffer_vec.push_back(0); //NUL terminated
197 |
198 | Vector auth_response;
199 | if (p_srvr_auth_type == AUTH_TYPE_MYSQL_NATIVE && (_client_auth_type == AUTH_TYPE_MYSQL_NATIVE))
200 | auth_response = get_mysql_native_password_hash(_password_hashed, p_srvr_salt);
201 |
202 | // if (server_capabilities & PLUGIN_AUTH_LENENC_CLIENT_DATA)
203 | // string authentication data
204 | // else if (server_capabilities & SECURE_CONNECTION) //mysql uses secure connection flag for transactions
205 | if (!(_server_capabilities & (uint64_t)Capabilities::CLIENT_MYSQL) &&
206 | (_server_capabilities & (uint64_t)Capabilities::SECURE_CONNECTION)) {
207 | //int<1> length of authentication response
208 | send_buffer_vec.push_back((uint8_t)auth_response.size());
209 | //string authentication response
210 | send_buffer_vec.append_array(auth_response);
211 | } else {
212 | //else string authentication response null ended
213 | send_buffer_vec.append_array(auth_response);
214 | send_buffer_vec.push_back(0); //NUL terminated
215 | }
216 |
217 | // if (server_capabilities & CLIENT_CONNECT_WITH_DB)
218 | // string default database name
219 | if (_client_capabilities & (uint64_t)Capabilities::CONNECT_WITH_DB) {
220 | send_buffer_vec.append_array(_dbname);
221 | send_buffer_vec.push_back(0); //NUL terminated
222 | }
223 |
224 | //if (server_capabilities & CLIENT_PLUGIN_AUTH)
225 | //string authentication plugin name
226 | Vector auth_plugin_name = kAuthTypeNames[(size_t)AUTH_TYPE_MYSQL_NATIVE].to_ascii_buffer();
227 | send_buffer_vec.append_array(auth_plugin_name);
228 | send_buffer_vec.push_back(0); //NUL terminated
229 |
230 | // Implementing CLIENT_SEND_CONNECT_ATTRS will just add more data, I don't think it is needed for game dev use
231 | // if (server_capabilities & CLIENT_SEND_CONNECT_ATTRS)
232 | //int size of connection attributes
233 | //while packet has remaining data
234 | //string key
235 | //string value
236 |
237 | m_add_packet_header(send_buffer_vec, ++seq_num);
238 | _stream.put_data(send_buffer_vec.ptr(), send_buffer_vec.size());
239 |
240 | srvr_response = m_recv_data(1000);
241 | size_t itr = 4;
242 |
243 | if (srvr_response.size() > 0) {
244 | //4th byte is seq should be 2
245 | seq_num = srvr_response[3];
246 | //5th byte is status
247 | uint8_t status = srvr_response[itr];
248 | if (status == 0x00) {
249 | _authenticated = true;
250 | return Error::OK;
251 | } else if (status == 0xFE) {
252 | user_auth_type = m_get_server_auth_type(m_find_vbytes_str_at(srvr_response, itr));
253 | } else if (status == 0xFF) {
254 | m_handle_server_error(srvr_response, itr);
255 | _authenticated = false;
256 | return Error::ERR_UNAUTHORIZED;
257 | } else {
258 | ERR_FAIL_V_EDMSG(Error::ERR_BUG, "Unhandled response code:" + String::num_uint64(srvr_response[itr], 16, true));
259 | }
260 | }
261 |
262 | if (user_auth_type == AUTH_TYPE_ED25519 && _client_auth_type == AUTH_TYPE_ED25519) {
263 | //srvr_auth_msg.assign(srvr_response.begin() + itr + 1, srvr_response.end());
264 | srvr_auth_msg.append_array(srvr_response.slice(itr + 1));
265 | auth_response = get_client_ed25519_signature(_password_hashed, srvr_auth_msg);
266 | send_buffer_vec = auth_response;
267 | } else {
268 | return Error::ERR_INVALID_PARAMETER;
269 | }
270 |
271 | m_add_packet_header(send_buffer_vec, ++seq_num);
272 |
273 | Error err = _stream.put_data(send_buffer_vec.ptr(), send_buffer_vec.size());
274 | ERR_FAIL_COND_V_MSG(err != Error::OK, err, "Failed to put data!");
275 |
276 | srvr_response = m_recv_data(1000);
277 |
278 | if (srvr_response.size() > 0) {
279 | //4th byte is seq should be 2
280 | seq_num = srvr_response[3];
281 | //5th byte is status
282 | itr = 4;
283 | if (srvr_response[itr] == 0x00) {
284 | _authenticated = true;
285 | } else if (srvr_response[itr] == 0xFF) {
286 | m_handle_server_error(srvr_response, itr);
287 | _authenticated = false;
288 | return Error::ERR_UNAUTHORIZED;
289 | } else {
290 | ERR_FAIL_V_MSG(Error::ERR_BUG, "Unhandled response code:" + String::num_uint64(srvr_response[itr], 16, true));
291 | }
292 | }
293 |
294 | return Error::OK;
295 | }
296 |
297 | Error MariaDB::m_connect() {
298 | disconnect_db();
299 |
300 | Error err;
301 | if (_ip.is_valid() && _port > 0) {
302 | err = _stream.connect_to_host(_ip, _port);
303 | } else {
304 | err = Error::ERR_INVALID_PARAMETER;
305 | }
306 |
307 | ERR_FAIL_COND_V_MSG(err != Error::OK, err, "Cannot connect to host with IP: " + String(_ip) + " and port: " + itos(_port));
308 |
309 | for (size_t i = 0; i < 1000; i++) {
310 | _stream.poll();
311 | if (_stream.get_status() == StreamPeerTCP::STATUS_CONNECTED) {
312 | break;
313 | } else {
314 | OS::get_singleton()->delay_usec(1000);
315 | }
316 | }
317 |
318 | ERR_FAIL_COND_V_MSG(_stream.get_status() != StreamPeerTCP::STATUS_CONNECTED, Error::ERR_CONNECTION_ERROR,
319 | "Cannot connect to host with IP: " + String(_ip) + " and port: " + itos(_port));
320 |
321 | // if (_stream.get_status() != StreamPeerTCP::STATUS_CONNECTED) {
322 | // ERR_FAIL_V_MSG(Error::ERR_CONNECTION_ERROR, "Can't connect to DB server!");
323 | // }
324 |
325 | Vector recv_buffer = m_recv_data(250);
326 | //std::cout << "recv_bfr:" << recv_buffer.size() << std::endl;
327 | if (recv_buffer.size() <= 4) {
328 | ERR_FAIL_V_MSG(Error::ERR_UNAVAILABLE, "connect: Recv buffer empty!");
329 | }
330 |
331 | // per https://mariadb.com/kb/en/connection/
332 | // The first packet from the server on a connection is a greeting giving/suggesting the requirements to login
333 |
334 | /* Per https://mariadb.com/kb/en/0-packet/
335 | * On all packet stages between packet segment the standard packet is sent
336 | * int<3> rcvd_bfr[0] to rcvd_bfr[2] First 3 bytes are packet length
337 | * int<1> rcvd_bfr[3] 4th byte is sequence number
338 | * byte rcvd_bfr[4] to rcvd_bfr[4 + n] remaining bytes are the packet body n = packet length
339 | */
340 |
341 | uint32_t packet_length = (uint32_t)recv_buffer[0] + ((uint32_t)recv_buffer[1] << 8) +
342 | ((uint32_t)recv_buffer[2] << 16);
343 | // On initial connect the packet length should be 4 byte less than buffer length
344 | if (packet_length != ((uint32_t)recv_buffer.size() - 4)) {
345 | ERR_FAIL_V_MSG(Error::FAILED, "Recv bfr does not match expected size!");
346 | }
347 |
348 | // 4th byte is sequence number, increment this when replying with login request, if client starts then start at 0
349 | if (recv_buffer[3] != 0) {
350 | ERR_FAIL_V_MSG(Error::FAILED, "Packet sequence error!");
351 | }
352 |
353 | // From the 5th byte on is the packet body
354 |
355 | /* 5th byte is protocol version, currently only 10 for MariaDB and MySQL v3.21.0+,
356 | * protocol version 9 for older MySQL versions.
357 | */
358 | if (recv_buffer[4] == 10) {
359 | m_server_init_handshake_v10(recv_buffer);
360 | } else {
361 | ERR_FAIL_V_MSG(Error::FAILED, "Protocol version incompatible!");
362 | }
363 |
364 | // _tcp_thread.start(m_tcp_thread_func, this);
365 |
366 | return Error::OK;
367 | } //m_connect
368 |
369 | // void MariaDB::m_tcp_thread_func(void *_instance) {
370 | // MariaDB *inst = (MariaDB *)_instance;
371 |
372 | // int byte_cnt = 0;
373 | // Vector rcv_bfr;
374 | // Vector transfer_bfr;
375 |
376 | // while (inst->_running) {
377 | // while (inst->_tcp_polling) {
378 | // if (! inst->is_connected_db())
379 | // continue;
380 | // byte_cnt = inst->_stream.get_available_bytes();
381 | // if (byte_cnt > 0) {
382 | // rcv_bfr.resize(byte_cnt);
383 | // inst->_stream.get_data(rcv_bfr.ptrw(), byte_cnt);
384 | // transfer_bfr.append_array(rcv_bfr);
385 | // }
386 |
387 | // if (transfer_bfr.size() > 0) {
388 | // inst->_tcp_mutex.lock();
389 | // inst->_tcp_thread_data.append_array(transfer_bfr);
390 | // transfer_bfr.clear();
391 | // inst->_tcp_mutex.unlock();
392 | // }
393 | // }
394 | // OS::get_singleton()->delay_usec(1000);
395 | // }
396 | // }
397 |
398 | Variant MariaDB::m_get_type_data(const int p_db_field_type, const PackedByteArray p_data) {
399 | String rtn_val;
400 | rtn_val.parse_utf8((const char *)p_data.ptr(), p_data.size());
401 | switch (p_db_field_type) {
402 | case 1: // MYSQL_TYPE_TINY
403 | case 2: // MYSQL_TYPE_SHORT
404 | case 3: // MYSQL_TYPE_LONG
405 | case 8: // MYSQL_TYPE_LONGLONG
406 | case 9: // MYSQL_TYPE_INT24 aka MEDIUM INT
407 | case 13: // MYSQL_TYPE_YEAR
408 | return rtn_val.to_int();
409 | break;
410 | case 0: // MYSQL_TYPE_DECIMAL
411 | case 4: // MYSQL_TYPE_FLOAT
412 | return rtn_val.to_float();
413 | break;
414 | case 5: // MYSQL_TYPE_DOUBLE
415 | if (_dbl_to_string) {
416 | return rtn_val;
417 | } else {
418 | return rtn_val.to_float();
419 | }
420 | break;
421 | default:
422 |
423 | return rtn_val;
424 | }
425 | return 0;
426 | }
427 |
428 | MariaDB::AuthType MariaDB::m_get_server_auth_type(String p_srvr_auth_name) {
429 | AuthType server_auth_type = AUTH_TYPE_ED25519;
430 | if (p_srvr_auth_name == "mysql_native_password") {
431 | server_auth_type = AUTH_TYPE_MYSQL_NATIVE;
432 | } else if (p_srvr_auth_name == "client_ed25519") {
433 | server_auth_type = AUTH_TYPE_ED25519;
434 | }
435 | //TODO(sigrudds1) Add cached_sha2 for mysql
436 | return server_auth_type;
437 | }
438 |
439 | Vector MariaDB::m_recv_data() {
440 | int byte_cnt = _stream.get_available_bytes();
441 | Vector recv_buffer;
442 | if (byte_cnt > 0) {
443 | recv_buffer.resize(byte_cnt);
444 | _stream.get_data(recv_buffer.ptrw(), byte_cnt);
445 | }
446 |
447 | return recv_buffer;
448 | }
449 |
450 | Vector MariaDB::m_recv_data(uint32_t p_timeout) {
451 | int byte_cnt = 0;
452 | // int rcvd_bytes = 0;
453 | Vector recv_buffer, out_buffer;
454 | uint64_t start_msec = OS::get_singleton()->get_ticks_msec();
455 | uint64_t time_lapse = 0;
456 | bool data_rcvd = false;
457 |
458 | while (is_connected_db() && time_lapse < p_timeout) {
459 | byte_cnt = _stream.get_available_bytes();
460 | if (byte_cnt > 0) {
461 | recv_buffer.resize(byte_cnt);
462 | _stream.get_data(recv_buffer.ptrw(), byte_cnt);
463 | data_rcvd = true;
464 | out_buffer.append_array(recv_buffer);
465 | start_msec = OS::get_singleton()->get_ticks_msec();
466 | } else if (data_rcvd) {
467 | break;
468 | }
469 | time_lapse = OS::get_singleton()->get_ticks_msec() - start_msec;
470 | }
471 |
472 | // if (out_buffer.size() > 0)
473 | // print_line("m_recv_data time_lapse:", time_lapse, " data:", out_buffer.size());
474 |
475 | return out_buffer;
476 | }
477 |
478 | void MariaDB::m_handle_server_error(const Vector p_src_buffer, size_t &p_last_pos) {
479 | //REF https://mariadb.com/kb/en/err_packet/
480 | uint16_t srvr_error_code = (uint16_t)p_src_buffer[++p_last_pos];
481 | srvr_error_code += (uint16_t)p_src_buffer[++p_last_pos] << 8;
482 | String msg = String::num_uint64((uint64_t)srvr_error_code) + " - ";
483 | if (srvr_error_code == 0xFFFF) {
484 | //int<1> stage
485 | //int<1> max_stage
486 | //int<3> progress
487 | //string progress_info
488 | } else {
489 | if (p_src_buffer[p_last_pos + 1] == '#') {
490 | msg += "SQL State:";
491 | for (size_t itr = 0; itr < 6; ++itr)
492 | msg += (char)p_src_buffer[++p_last_pos];
493 | msg += " - ";
494 | while (p_last_pos < (size_t)p_src_buffer.size() - 1) {
495 | msg += (char)p_src_buffer[++p_last_pos];
496 | }
497 | } else {
498 | //string human - readable error message
499 | while (p_last_pos < (size_t)p_src_buffer.size() - 1) {
500 | msg += (char)p_src_buffer[++p_last_pos];
501 | }
502 | }
503 | }
504 | ERR_FAIL_COND_EDMSG(srvr_error_code != OK, msg);
505 | }
506 |
507 | String MariaDB::m_find_vbytes_str(Vector p_buf) {
508 | size_t start_pos = 0;
509 | return m_find_vbytes_str_at(p_buf, start_pos);
510 | }
511 |
512 | String MariaDB::m_find_vbytes_str_at(Vector p_buf, size_t &p_start_pos) {
513 | Vector vc;
514 | while (p_buf[++p_start_pos] != 0 && p_start_pos < (size_t)p_buf.size()) {
515 | vc.push_back(p_buf[p_start_pos]);
516 | }
517 | vc.push_back(0); //for proper char * string convertion
518 | return (String)vc.ptr();
519 | }
520 |
521 | PackedByteArray MariaDB::m_get_pkt_bytes(const Vector &p_src_buf, size_t &p_start_pos,
522 | const size_t p_byte_cnt){
523 |
524 | PackedByteArray rtn;
525 | if (p_byte_cnt <= 0 || p_start_pos + p_byte_cnt > (size_t)p_src_buf.size()) {
526 | return rtn;
527 | }
528 | rtn = p_src_buf.slice(p_start_pos, p_start_pos + p_byte_cnt);
529 | p_start_pos += p_byte_cnt - 1;
530 | return rtn;
531 | }
532 |
533 | size_t MariaDB::m_get_pkt_len_at(const Vector p_src_buf, size_t &p_start_pos) {
534 | size_t len = (size_t)p_src_buf[p_start_pos];
535 | len += (size_t)p_src_buf[++p_start_pos] << 8;
536 | len += (size_t)p_src_buf[++p_start_pos] << 16;
537 | return len;
538 | }
539 |
540 | Error MariaDB::m_server_init_handshake_v10(const Vector &p_src_buffer) {
541 | Vector v_chr_temp;
542 |
543 | //nul string - read the 5th byte until the first nul(00), this is server version string, it is nul terminated
544 | size_t pkt_itr = 3;
545 | _server_ver_str = "";
546 | while (p_src_buffer[++pkt_itr] != 0 && pkt_itr < (size_t)p_src_buffer.size()) {
547 | _server_ver_str += (char)p_src_buffer[pkt_itr];
548 | }
549 |
550 | _server_ver_str = _server_ver_str.strip_escapes();
551 |
552 | if (_server_ver_str.begins_with("5.5.5-")) {
553 | PackedStringArray split_ver_str = _server_ver_str.split("-");
554 | PackedStringArray split_ver_str_seg = split_ver_str[1].split(".");
555 |
556 | _srvr_major_ver = split_ver_str_seg[0].to_int();
557 | _srvr_minor_ver = split_ver_str_seg[1].to_int();
558 | }
559 |
560 | //4bytes - doesn't appear to be needed.
561 | pkt_itr += 4;
562 |
563 | //salt part 1 - 8 bytes
564 | Vector server_salt;
565 | for (size_t j = 0; j < 8; j++)
566 | server_salt.push_back(p_src_buffer[++pkt_itr]);
567 |
568 | //reserved byte
569 | pkt_itr++;
570 |
571 | _server_capabilities = 0;
572 | //2bytes -server capabilities part 1
573 | _server_capabilities = (uint64_t)p_src_buffer[++pkt_itr];
574 | _server_capabilities += ((uint64_t)p_src_buffer[++pkt_itr]) << 8;
575 |
576 | //1byte - server default collation code
577 | ++pkt_itr;
578 |
579 | //2bytes - Status flags
580 | //uint16_t status = 0;
581 | //status = (uint16_t)p_src_buffer[++pkt_itr];
582 | //status += ((uint16_t)p_src_buffer[++pkt_itr]) << 8;
583 | pkt_itr += 2;
584 |
585 | //2bytes - server capabilities part 2
586 | _server_capabilities += ((uint64_t)p_src_buffer[++pkt_itr]) << 16;
587 | _server_capabilities += ((uint64_t)p_src_buffer[++pkt_itr]) << 24;
588 |
589 | if (!(_server_capabilities & (uint64_t)Capabilities::CLIENT_PROTOCOL_41)) {
590 | ERR_FAIL_V_MSG(Error::FAILED, "Incompatible authorization protocol!");
591 | }
592 | //TODO(sigrudds1) Make auth plugin not required if using ssl/tls
593 | if (!(_server_capabilities & (uint64_t)Capabilities::PLUGIN_AUTH)) {
594 | ERR_FAIL_V_MSG(Error::FAILED, "Authorization protocol not set!");
595 | }
596 |
597 | //1byte - salt length 0 for none
598 | uint8_t server_salt_length = p_src_buffer[++pkt_itr];
599 |
600 | //6bytes - filler
601 | pkt_itr += 6;
602 |
603 | // 4bytes - filler or server capabilities part 3 (mariadb v10.2 or later) "MariaDB extended capablities"
604 | if (!(_server_capabilities & (uint64_t)Capabilities::CLIENT_MYSQL) &&
605 | _srvr_major_ver >= 10 && _srvr_minor_ver >= 2) {
606 | _server_capabilities += ((uint64_t)p_src_buffer[++pkt_itr]) << 32;
607 | _server_capabilities += ((uint64_t)p_src_buffer[++pkt_itr]) << 40;
608 | _server_capabilities += ((uint64_t)p_src_buffer[++pkt_itr]) << 48;
609 | _server_capabilities += ((uint64_t)p_src_buffer[++pkt_itr]) << 56;
610 | } else {
611 | pkt_itr += 4;
612 | }
613 |
614 | //12bytes - salt part 2
615 | for (size_t j = 0; j < (size_t)std::max(13, server_salt_length - 8); j++)
616 | server_salt.push_back(p_src_buffer[++pkt_itr]);
617 |
618 | //1byte - reserved
619 | //nul string - auth plugin name, length = auth plugin string length
620 |
621 | v_chr_temp.clear();
622 | while (p_src_buffer[++pkt_itr] != 0 && pkt_itr < (size_t)p_src_buffer.size()) {
623 | v_chr_temp.push_back(p_src_buffer[pkt_itr]);
624 | }
625 | v_chr_temp.push_back(0); //for proper char * string convertion
626 |
627 | //determine which auth method the server can use
628 | AuthType p_srvr_auth_type = m_get_server_auth_type((String)v_chr_temp.ptr());
629 |
630 | return m_client_protocol_v41(p_srvr_auth_type, server_salt);
631 | } //server_init_handshake_v10
632 |
633 | void MariaDB::m_update_password(String p_password) {
634 | if (_is_pre_hashed)
635 | return;
636 |
637 | //take the password and store it as the hash, only the hash is needed
638 | if (_client_auth_type == AUTH_TYPE_MYSQL_NATIVE) {
639 | _password_hashed = p_password.sha1_buffer();
640 | } else if (_client_auth_type == AUTH_TYPE_ED25519) {
641 | _password_hashed.resize(64);
642 | void *ctx = memalloc(sizeof(mbedtls_sha512_context));
643 | mbedtls_sha512_init((mbedtls_sha512_context *)ctx);
644 | mbedtls_sha512_starts_ret((mbedtls_sha512_context *)ctx, 0);
645 | mbedtls_sha512_update_ret((mbedtls_sha512_context *)ctx, (uint8_t *)p_password.ascii().ptr(),
646 | p_password.length());
647 | mbedtls_sha512_finish_ret((mbedtls_sha512_context *)ctx, _password_hashed.ptrw());
648 | mbedtls_sha512_free((mbedtls_sha512_context *)ctx);
649 | memfree((mbedtls_sha512_context *)ctx);
650 | }
651 |
652 | //TODO(sigrudds1) mysql caching_sha2_password
653 | }
654 |
655 | void MariaDB::m_update_username(String p_username) {
656 | _username = p_username.to_ascii_buffer();
657 | }
658 |
659 | //public
660 | Error MariaDB::connect_db(String p_host, int p_port, String p_dbname, String p_username, String p_hashed_password,
661 | AuthType p_authtype, bool p_is_prehashed) {
662 | IPAddress ip;
663 |
664 | if (p_host.is_valid_ip_address()) {
665 | _ip = p_host;
666 | } else {
667 | _ip = IP::get_singleton()->resolve_hostname(p_host, (IP::Type)_ip_type);
668 | }
669 | _port = p_port;
670 | // _tcp_polling = false;
671 | // _running = true;
672 |
673 | _client_auth_type = p_authtype;
674 | _is_pre_hashed = p_is_prehashed;
675 |
676 | if (p_username.size() <= 0) {
677 | ERR_PRINT("username not set");
678 | return Error::ERR_INVALID_PARAMETER;
679 | }
680 |
681 | if (p_hashed_password.size() <= 0) {
682 | ERR_PRINT("password not set");
683 | return Error::ERR_INVALID_PARAMETER;
684 | }
685 |
686 | if (p_dbname.length() <= 0 && _client_capabilities & (uint64_t)Capabilities::CONNECT_WITH_DB) {
687 | ERR_PRINT("dbname not set");
688 | return Error::ERR_INVALID_PARAMETER;
689 | } else {
690 | set_db_name(p_dbname);
691 | }
692 |
693 | m_update_username(p_username);
694 |
695 | if (p_is_prehashed) {
696 | _password_hashed = hex_str_to_v_bytes(p_hashed_password);
697 | } else {
698 | m_update_password(p_hashed_password);
699 | }
700 |
701 | return m_connect();
702 | }
703 |
704 | void MariaDB::disconnect_db() {
705 | // _tcp_polling = false;
706 | if (is_connected_db()) {
707 | //say goodbye too the server
708 | uint8_t output[5] = { 0x01, 0x00, 0x00, 0x00, 0x01 };
709 | _stream.put_data(output, 5);
710 | _stream.disconnect_from_host();
711 | }
712 | _authenticated = false;
713 | }
714 |
715 | String MariaDB::get_last_query() {
716 | return _last_query;
717 | }
718 |
719 | PackedByteArray MariaDB::get_last_query_converted() {
720 | return _last_query_converted;
721 | }
722 |
723 | PackedByteArray MariaDB::get_last_response() {
724 | return _last_response;
725 | }
726 |
727 | PackedByteArray MariaDB::get_last_transmitted() {
728 | return _last_transmitted;
729 | }
730 |
731 | bool MariaDB::is_connected_db() {
732 | _stream.poll();
733 | return _stream.get_status() == StreamPeerTCP::STATUS_CONNECTED;
734 | }
735 |
736 | Variant MariaDB::query(String sql_stmt) {
737 | if (!is_connected_db())
738 | return (uint32_t)ERR_NOT_CONNECTED;
739 | if (!_authenticated)
740 | return (uint32_t)ERR_AUTH_FAILED;
741 |
742 | // _tcp_polling = true;
743 |
744 | _last_query = sql_stmt;
745 | Vector send_buffer_vec;
746 | int bfr_size = 0;
747 |
748 | /* For interest of speed over memory I am working with the entire buffer
749 | * and keeping track of the iteration point, as most queries for
750 | * game dev should be small but speedy.
751 | */
752 |
753 | size_t pkt_itr = 0;
754 | size_t pkt_len; //techinically section length everything arrives in one stream packet
755 | size_t len_encode = 0;
756 | bool done = false;
757 | // From MariaDB version 10.2 dep_eof should be true
758 | bool dep_eof = (_client_capabilities & (uint64_t)Capabilities::CLIENT_DEPRECATE_EOF);
759 |
760 | Vector col_data;
761 |
762 | send_buffer_vec.push_back(0x03);
763 | _last_query_converted = sql_stmt.to_utf8_buffer();
764 |
765 | send_buffer_vec.append_array(_last_query_converted);
766 | m_add_packet_header(send_buffer_vec, 0);
767 |
768 | _last_transmitted = send_buffer_vec;
769 | // _tcp_mutex.lock();
770 | _stream.put_data(send_buffer_vec.ptr(), send_buffer_vec.size());
771 | // _tcp_mutex.unlock();
772 |
773 | Vector srvr_response = m_recv_data(1000);
774 | // m_append_thread_data(srvr_response);
775 | bfr_size = srvr_response.size();
776 |
777 | // srvr_response = m_recv_data(1000);
778 | if (bfr_size == 0) {
779 | return (uint32_t)ERR_NO_RESPONSE;
780 | }
781 |
782 | pkt_len = m_get_pkt_len_at(srvr_response, pkt_itr);
783 |
784 | // uint8_t seq_num = srvr_response[++pkt_itr];
785 | ++pkt_itr;
786 |
787 | /* https://mariadb.com/kb/en/result-set-packets/
788 | * The pkt_itr should be at 3, we are on teh 4th byte and wlll iterate before use
789 | * Resultset metadata
790 | * All segment packets start with packet length(3 bytes) and sequence number
791 | * This is a small packet with packet length of 1 to 9 of 4 to 19 bytes
792 | * to determine how many columns of data are being sent.
793 | */
794 |
795 | uint64_t col_cnt = 0;
796 | uint8_t test = srvr_response[++pkt_itr];
797 | // https://mariadb.com/kb/en/protocol-data-types/#length-encoded-integers
798 | if (test == 0xFF) {
799 | int err = srvr_response[pkt_itr + 1] + (srvr_response[pkt_itr + 2] << 8);
800 | m_handle_server_error(srvr_response, pkt_itr);
801 | return err;
802 | } else if (test == 0xFE) {
803 | col_cnt = bytes_to_num_itr_pos(srvr_response.ptr(), 8, pkt_itr);
804 | } else if (test == 0xFD) {
805 | col_cnt = bytes_to_num_itr_pos(srvr_response.ptr(), 3, pkt_itr);
806 | } else if (test == 0xFC) {
807 | col_cnt = bytes_to_num_itr_pos(srvr_response.ptr(), 2, pkt_itr);
808 | } else if (test == 0xFB) {
809 | // null value
810 | // TODO needs investigation, not sure why this would happen
811 | } else if (test == 0x00) {
812 | return 0;
813 | } else {
814 | col_cnt = srvr_response[pkt_itr];
815 | }
816 | if (_client_capabilities & (uint64_t)Capabilities::MARIADB_CLIENT_CACHE_METADATA) {
817 | // print_line("send metadata:", srvr_response[++pkt_itr] == true);
818 | ++pkt_itr;
819 | }
820 | // for each column (i.e column_count times)
821 | for (size_t itr = 0; itr < col_cnt; ++itr) {
822 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, 24) != OK, ERR_PACKET_LENGTH_MISMATCH,
823 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + 24));
824 |
825 | pkt_len = m_get_pkt_len_at(srvr_response, ++pkt_itr);
826 |
827 | // seq_num = srvr_response[++pkt_itr];
828 | ++pkt_itr;
829 |
830 | // Column Definition packet
831 | // https://mariadb.com/kb/en/result-set-packets/#column-definition-packet
832 |
833 | // string catalog (always 'def')
834 | len_encode = srvr_response[++pkt_itr];
835 | vbytes_to_utf8_itr_at(srvr_response, pkt_itr, len_encode);
836 |
837 | // string schema (database name)
838 | len_encode = srvr_response[++pkt_itr];
839 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, len_encode) != OK, ERR_PACKET_LENGTH_MISMATCH,
840 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + len_encode));
841 | vbytes_to_utf8_itr_at(srvr_response, pkt_itr, len_encode);
842 |
843 | // string table alias
844 | len_encode = srvr_response[++pkt_itr];
845 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, len_encode) != OK, ERR_PACKET_LENGTH_MISMATCH,
846 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + len_encode));
847 | vbytes_to_utf8_itr_at(srvr_response, pkt_itr, len_encode);
848 |
849 | // string table
850 | len_encode = srvr_response[++pkt_itr];
851 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, len_encode) != OK, ERR_PACKET_LENGTH_MISMATCH,
852 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + len_encode));
853 | vbytes_to_utf8_itr_at(srvr_response, pkt_itr, len_encode);
854 |
855 | // string column alias
856 | len_encode = srvr_response[++pkt_itr];
857 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, len_encode) != OK, ERR_PACKET_LENGTH_MISMATCH,
858 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + len_encode));
859 | String column_name = vbytes_to_utf8_itr_at(srvr_response, pkt_itr, len_encode);
860 |
861 | // string column
862 | len_encode = srvr_response[++pkt_itr];
863 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, len_encode) != OK, ERR_PACKET_LENGTH_MISMATCH,
864 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + len_encode));
865 | vbytes_to_utf8_itr_at(srvr_response, pkt_itr, len_encode);
866 |
867 | // TODO(sigrudds1) Handle "MariaDB extended capablities" (several locations)
868 | // if extended type supported (see MARIADB_CLIENT_EXTENDED_TYPE_INFO )
869 | // int length extended info
870 | // loop
871 | // int<1> data type: 0x00:type, 0x01: format
872 | // string value
873 |
874 | // int length of fixed fields (=0xC)
875 | uint8_t remaining = srvr_response[++pkt_itr];
876 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, remaining) != OK, ERR_PACKET_LENGTH_MISMATCH,
877 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + remaining));
878 | // ++pkt_itr; //remaining bytes in packet section
879 |
880 | // int<2> character set number
881 | uint16_t char_set = bytes_to_num_itr_pos(srvr_response.ptr(), 2, pkt_itr);
882 | // print_line("char set id:", char_set);
883 |
884 | // int<4> max. column size the number in parenthesis eg int(10), varchar(255)
885 | // uint32_t col_size = bytes_to_num_itr(srvr_response.data(), 4, pkt_itr);
886 | pkt_itr += 4;
887 |
888 | // int<1> Field types
889 | // https://mariadb.com/kb/en/result-set-packets/#field-types
890 | uint8_t field_type = srvr_response[++pkt_itr];
891 |
892 | // int<2> Field detail flag
893 | // https://mariadb.com/kb/en/result-set-packets/#field-details-flag
894 | pkt_itr += 2;
895 |
896 | // int<1> decimals
897 | pkt_itr += 1;
898 | // int<2> - unused -
899 | pkt_itr += 2;
900 |
901 | col_data.push_back({ column_name, char_set, field_type });
902 | }
903 |
904 | // if not (CLIENT_DEPRECATE_EOF capability set) get EOF_Packet
905 | if (!dep_eof) {
906 | pkt_itr += 5; //bypass for now
907 | }
908 |
909 | Array arr;
910 |
911 | //process values
912 | while (!done && pkt_itr < (size_t)srvr_response.size()) {
913 | // Last packet is always 11 byte, pkt len code= 3 bytes, seq= 1 byte, pkt data = 7 bytes
914 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, 11) != OK, ERR_PACKET_LENGTH_MISMATCH,
915 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + 11));
916 |
917 | pkt_len = m_get_pkt_len_at(srvr_response, ++pkt_itr);
918 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, pkt_len) != OK, ERR_PACKET_LENGTH_MISMATCH,
919 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + pkt_len));
920 |
921 | // seq_num = srvr_response[++pkt_itr];
922 | ++pkt_itr;
923 | test = srvr_response[pkt_itr + 1];
924 |
925 | if (test == 0xFE && dep_eof && pkt_len < 0xFFFFFF) {
926 | done = true;
927 | break;
928 | }
929 | Dictionary dict;
930 | //https://mariadb.com/kb/en/protocol-data-types/#length-encoded-strings
931 | for (size_t itr = 0; itr < col_cnt; ++itr) {
932 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, 2) != OK, ERR_PACKET_LENGTH_MISMATCH, vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + 2));
933 | test = srvr_response[++pkt_itr];
934 | if (test == 0xFF) {
935 | //ERR_Packet
936 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, 2) != OK, ERR_PACKET_LENGTH_MISMATCH, vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + 2));
937 | // Don't think these two if's are needed for column data
938 | // } else if ((test == 0x00 && !dep_eof /* && pkt_len < 0xFFFFFF */) ||
939 | // (test == 0xFE && pkt_len < 0xFFFFFF && dep_eof)) {
940 | // //OK_Packet
941 | // done = true;
942 | // break;
943 | // } else if (test == 0xFE && pkt_len < 0xFFFFFF && !dep_eof) {
944 | // //EOF_Packet
945 | // done = true;
946 | // break;
947 | } else {
948 | if (test == 0xFE) {
949 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, 8) != OK, ERR_PACKET_LENGTH_MISMATCH, vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + 8));
950 | len_encode = bytes_to_num_itr_pos(srvr_response.ptr(), 8, pkt_itr);
951 | } else if (test == 0xFD) {
952 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, 3) != OK, ERR_PACKET_LENGTH_MISMATCH, vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + 3));
953 | len_encode = bytes_to_num_itr_pos(srvr_response.ptr(), 3, pkt_itr);
954 | } else if (test == 0xFC) {
955 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, 2) != OK, ERR_PACKET_LENGTH_MISMATCH, vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + 2));
956 | len_encode = bytes_to_num_itr_pos(srvr_response.ptr(), 2, pkt_itr);
957 | } else if (test == 0xFB) {
958 | //null value need to skip
959 | len_encode = 0;
960 | } else {
961 | len_encode = srvr_response[pkt_itr];
962 | }
963 |
964 | ERR_FAIL_COND_V_EDMSG(m_chk_rcv_bfr(srvr_response, bfr_size, pkt_itr, len_encode) != OK, ERR_PACKET_LENGTH_MISMATCH,
965 | vformat("ERR_PACKET_LENGTH_MISMATCH rcvd %d expect %d", bfr_size, pkt_itr + len_encode));
966 | if (len_encode > 0) {
967 | PackedByteArray data = m_get_pkt_bytes(srvr_response, ++pkt_itr, len_encode);
968 | dict[col_data[itr].name] = m_get_type_data(col_data[itr].field_type, data);
969 | } else {
970 | dict[col_data[itr].name] = Variant();
971 | }
972 | }
973 | }
974 |
975 | if (!done)
976 | arr.push_back(dict);
977 | }
978 | // _tcp_polling = false;
979 | _last_response = PackedByteArray(srvr_response);
980 |
981 | return Variant(arr);
982 | }
983 |
984 | void MariaDB::set_dbl_to_string(bool p_is_to_str) {
985 | _dbl_to_string = p_is_to_str;
986 | }
987 |
988 | // TODO If db is not the same and connected then change db on server
989 | void MariaDB::set_db_name(String p_dbname) {
990 | _dbname = p_dbname.to_utf8_buffer();
991 | // _dbname = p_dbname.to_ascii_buffer(); // TODO Add character set compatibility??
992 | }
993 |
994 | void MariaDB::set_ip_type(IpType p_type) {
995 | _ip_type = p_type;
996 | }
997 |
--------------------------------------------------------------------------------
/ed25519_ref10/ed25519_fe.cpp:
--------------------------------------------------------------------------------
1 | /*************************************************************************/
2 | /* ed25519_fe.cpp */
3 | /*************************************************************************/
4 | /* This file is part of the */
5 | /* Maria and Mysql database connection module */
6 | /* for use in the Godot Engine */
7 | /* GODOT ENGINE */
8 | /* https://godotengine.org */
9 | /* This file was derived from information found at */
10 | /* https://tools.ietf.org/html/rfc8032#page-44 */
11 | /*************************************************************************/
12 | /* Copyright (c) 2021 Shawn Shipton. https://vikingtinkerer.com */
13 | /* */
14 | /* Permission is hereby granted, free of charge, to any person obtaining */
15 | /* a copy of this software and associated documentation files (the */
16 | /* "Software"), to deal in the Software without restriction, including */
17 | /* without limitation the rights to use, copy, modify, merge, publish, */
18 | /* distribute, sublicense, and/or sell copies of the Software, and to */
19 | /* permit persons to whom the Software is furnished to do so, subject to */
20 | /* the following conditions: */
21 | /* */
22 | /* The above copyright notice and this permission notice shall be */
23 | /* included in all copies or substantial portions of the Software. */
24 | /* */
25 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
26 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
27 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
28 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
29 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
30 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
31 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
32 | /*************************************************************************/
33 |
34 | #include "ed25519_fe.h"
35 | #include
36 |
37 | //#include
38 | //#include
39 | //#include
40 |
41 | static uint64_t bytes_to_u64(const uint8_t *src, size_t byte_count) {
42 | uint64_t result = 0;
43 |
44 | for (size_t i = 0; i < byte_count; ++i)
45 | result |= static_cast(src[i]) << (i * 8);
46 | return result;
47 | }
48 |
49 | void fe_0(fe h) {
50 | h[0] = 0;
51 | h[1] = 0;
52 | h[2] = 0;
53 | h[3] = 0;
54 | h[4] = 0;
55 | h[5] = 0;
56 | h[6] = 0;
57 | h[7] = 0;
58 | h[8] = 0;
59 | h[9] = 0;
60 | }
61 |
62 | /*
63 | h = 1
64 | */
65 |
66 | void fe_1(fe h) {
67 | h[0] = 1;
68 | h[1] = 0;
69 | h[2] = 0;
70 | h[3] = 0;
71 | h[4] = 0;
72 | h[5] = 0;
73 | h[6] = 0;
74 | h[7] = 0;
75 | h[8] = 0;
76 | h[9] = 0;
77 | }
78 |
79 | /*
80 | h = f + g
81 | Can overlap h with f or g.
82 |
83 | Preconditions:
84 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
85 | |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
86 |
87 | Postconditions:
88 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
89 | */
90 |
91 | void fe_add(fe h, const fe f, const fe g) {
92 | for (size_t i = 0; i < 10; ++i)
93 | h[i] = f[i] + g[i];
94 | }
95 |
96 | /*
97 | Replace (f,g) with (g,g) if b == 1;
98 | replace (f,g) with (f,g) if b == 0.
99 |
100 | Preconditions: b in {0,1}.
101 | */
102 |
103 | void fe_cmov(fe f, const fe g, unsigned int b) {
104 | int32_t f0 = f[0];
105 | int32_t f1 = f[1];
106 | int32_t f2 = f[2];
107 | int32_t f3 = f[3];
108 | int32_t f4 = f[4];
109 | int32_t f5 = f[5];
110 | int32_t f6 = f[6];
111 | int32_t f7 = f[7];
112 | int32_t f8 = f[8];
113 | int32_t f9 = f[9];
114 | int32_t g0 = g[0];
115 | int32_t g1 = g[1];
116 | int32_t g2 = g[2];
117 | int32_t g3 = g[3];
118 | int32_t g4 = g[4];
119 | int32_t g5 = g[5];
120 | int32_t g6 = g[6];
121 | int32_t g7 = g[7];
122 | int32_t g8 = g[8];
123 | int32_t g9 = g[9];
124 | int32_t x0 = f0 ^ g0;
125 | int32_t x1 = f1 ^ g1;
126 | int32_t x2 = f2 ^ g2;
127 | int32_t x3 = f3 ^ g3;
128 | int32_t x4 = f4 ^ g4;
129 | int32_t x5 = f5 ^ g5;
130 | int32_t x6 = f6 ^ g6;
131 | int32_t x7 = f7 ^ g7;
132 | int32_t x8 = f8 ^ g8;
133 | int32_t x9 = f9 ^ g9;
134 |
135 | b = (unsigned int)(-(int)b); /* silence warning */
136 | x0 &= b;
137 | x1 &= b;
138 | x2 &= b;
139 | x3 &= b;
140 | x4 &= b;
141 | x5 &= b;
142 | x6 &= b;
143 | x7 &= b;
144 | x8 &= b;
145 | x9 &= b;
146 |
147 | f[0] = f0 ^ x0;
148 | f[1] = f1 ^ x1;
149 | f[2] = f2 ^ x2;
150 | f[3] = f3 ^ x3;
151 | f[4] = f4 ^ x4;
152 | f[5] = f5 ^ x5;
153 | f[6] = f6 ^ x6;
154 | f[7] = f7 ^ x7;
155 | f[8] = f8 ^ x8;
156 | f[9] = f9 ^ x9;
157 | }
158 |
159 | /*
160 | Replace (f,g) with (g,f) if b == 1;
161 | replace (f,g) with (f,g) if b == 0.
162 |
163 | Preconditions: b in {0,1}.
164 | */
165 |
166 | void fe_cswap(fe f, fe g, unsigned int b) {
167 | int32_t f0 = f[0];
168 | int32_t f1 = f[1];
169 | int32_t f2 = f[2];
170 | int32_t f3 = f[3];
171 | int32_t f4 = f[4];
172 | int32_t f5 = f[5];
173 | int32_t f6 = f[6];
174 | int32_t f7 = f[7];
175 | int32_t f8 = f[8];
176 | int32_t f9 = f[9];
177 | int32_t g0 = g[0];
178 | int32_t g1 = g[1];
179 | int32_t g2 = g[2];
180 | int32_t g3 = g[3];
181 | int32_t g4 = g[4];
182 | int32_t g5 = g[5];
183 | int32_t g6 = g[6];
184 | int32_t g7 = g[7];
185 | int32_t g8 = g[8];
186 | int32_t g9 = g[9];
187 | int32_t x0 = f0 ^ g0;
188 | int32_t x1 = f1 ^ g1;
189 | int32_t x2 = f2 ^ g2;
190 | int32_t x3 = f3 ^ g3;
191 | int32_t x4 = f4 ^ g4;
192 | int32_t x5 = f5 ^ g5;
193 | int32_t x6 = f6 ^ g6;
194 | int32_t x7 = f7 ^ g7;
195 | int32_t x8 = f8 ^ g8;
196 | int32_t x9 = f9 ^ g9;
197 | b = (unsigned int)(-(int)b); /* silence warning */
198 | x0 &= b;
199 | x1 &= b;
200 | x2 &= b;
201 | x3 &= b;
202 | x4 &= b;
203 | x5 &= b;
204 | x6 &= b;
205 | x7 &= b;
206 | x8 &= b;
207 | x9 &= b;
208 | f[0] = f0 ^ x0;
209 | f[1] = f1 ^ x1;
210 | f[2] = f2 ^ x2;
211 | f[3] = f3 ^ x3;
212 | f[4] = f4 ^ x4;
213 | f[5] = f5 ^ x5;
214 | f[6] = f6 ^ x6;
215 | f[7] = f7 ^ x7;
216 | f[8] = f8 ^ x8;
217 | f[9] = f9 ^ x9;
218 | g[0] = g0 ^ x0;
219 | g[1] = g1 ^ x1;
220 | g[2] = g2 ^ x2;
221 | g[3] = g3 ^ x3;
222 | g[4] = g4 ^ x4;
223 | g[5] = g5 ^ x5;
224 | g[6] = g6 ^ x6;
225 | g[7] = g7 ^ x7;
226 | g[8] = g8 ^ x8;
227 | g[9] = g9 ^ x9;
228 | }
229 |
230 | /*
231 | h = f
232 | */
233 |
234 | void fe_copy(fe h, const fe f) {
235 | int32_t f0 = f[0];
236 | int32_t f1 = f[1];
237 | int32_t f2 = f[2];
238 | int32_t f3 = f[3];
239 | int32_t f4 = f[4];
240 | int32_t f5 = f[5];
241 | int32_t f6 = f[6];
242 | int32_t f7 = f[7];
243 | int32_t f8 = f[8];
244 | int32_t f9 = f[9];
245 |
246 | h[0] = f0;
247 | h[1] = f1;
248 | h[2] = f2;
249 | h[3] = f3;
250 | h[4] = f4;
251 | h[5] = f5;
252 | h[6] = f6;
253 | h[7] = f7;
254 | h[8] = f8;
255 | h[9] = f9;
256 | }
257 |
258 | /*
259 | Ignores top bit of h.
260 | */
261 | void fe_frombytes(fe h, const uint8_t *s) {
262 | int64_t h0 = bytes_to_u64(s, 4);
263 | int64_t h1 = bytes_to_u64(s + 4, 3) << 6;
264 | int64_t h2 = bytes_to_u64(s + 7, 3) << 5;
265 | int64_t h3 = bytes_to_u64(s + 10, 3) << 3;
266 | int64_t h4 = bytes_to_u64(s + 13, 3) << 2;
267 | int64_t h5 = bytes_to_u64(s + 16, 4);
268 | int64_t h6 = bytes_to_u64(s + 20, 3) << 7;
269 | int64_t h7 = bytes_to_u64(s + 23, 3) << 5;
270 | int64_t h8 = bytes_to_u64(s + 26, 3) << 4;
271 | int64_t h9 = (bytes_to_u64(s + 29, 3) & 8388607) << 2;
272 | int64_t carry0;
273 | int64_t carry1;
274 | int64_t carry2;
275 | int64_t carry3;
276 | int64_t carry4;
277 | int64_t carry5;
278 | int64_t carry6;
279 | int64_t carry7;
280 | int64_t carry8;
281 | int64_t carry9;
282 |
283 | carry9 = (h9 + (int64_t)(1 << 24)) >> 25;
284 | h0 += carry9 * 19;
285 | h9 -= carry9 << 25;
286 | carry1 = (h1 + (int64_t)(1 << 24)) >> 25;
287 | h2 += carry1;
288 | h1 -= carry1 << 25;
289 | carry3 = (h3 + (int64_t)(1 << 24)) >> 25;
290 | h4 += carry3;
291 | h3 -= carry3 << 25;
292 | carry5 = (h5 + (int64_t)(1 << 24)) >> 25;
293 | h6 += carry5;
294 | h5 -= carry5 << 25;
295 | carry7 = (h7 + (int64_t)(1 << 24)) >> 25;
296 | h8 += carry7;
297 | h7 -= carry7 << 25;
298 | carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
299 | h1 += carry0;
300 | h0 -= carry0 << 26;
301 | carry2 = (h2 + (int64_t)(1 << 25)) >> 26;
302 | h3 += carry2;
303 | h2 -= carry2 << 26;
304 | carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
305 | h5 += carry4;
306 | h4 -= carry4 << 26;
307 | carry6 = (h6 + (int64_t)(1 << 25)) >> 26;
308 | h7 += carry6;
309 | h6 -= carry6 << 26;
310 | carry8 = (h8 + (int64_t)(1 << 25)) >> 26;
311 | h9 += carry8;
312 | h8 -= carry8 << 26;
313 |
314 | h[0] = (int32_t)h0;
315 | h[1] = (int32_t)h1;
316 | h[2] = (int32_t)h2;
317 | h[3] = (int32_t)h3;
318 | h[4] = (int32_t)h4;
319 | h[5] = (int32_t)h5;
320 | h[6] = (int32_t)h6;
321 | h[7] = (int32_t)h7;
322 | h[8] = (int32_t)h8;
323 | h[9] = (int32_t)h9;
324 | }
325 |
326 | void fe_invert(fe out, const fe z) {
327 | fe t0;
328 | fe t1;
329 | fe t2;
330 | fe t3;
331 | int i;
332 |
333 | fe_sq(t0, z);
334 |
335 | //for (i = 1; i < 1; ++i) {
336 | // fe_sq(t0, t0);
337 | //}
338 |
339 | fe_sq(t1, t0);
340 |
341 | for (i = 1; i < 2; ++i) {
342 | fe_sq(t1, t1);
343 | }
344 |
345 | fe_mul(t1, z, t1);
346 | fe_mul(t0, t0, t1);
347 | fe_sq(t2, t0);
348 |
349 | //for (i = 1; i < 1; ++i) {
350 | // fe_sq(t2, t2);
351 | //}
352 |
353 | fe_mul(t1, t1, t2);
354 | fe_sq(t2, t1);
355 |
356 | for (i = 1; i < 5; ++i) {
357 | fe_sq(t2, t2);
358 | }
359 |
360 | fe_mul(t1, t2, t1);
361 | fe_sq(t2, t1);
362 |
363 | for (i = 1; i < 10; ++i) {
364 | fe_sq(t2, t2);
365 | }
366 |
367 | fe_mul(t2, t2, t1);
368 | fe_sq(t3, t2);
369 |
370 | for (i = 1; i < 20; ++i) {
371 | fe_sq(t3, t3);
372 | }
373 |
374 | fe_mul(t2, t3, t2);
375 | fe_sq(t2, t2);
376 |
377 | for (i = 1; i < 10; ++i) {
378 | fe_sq(t2, t2);
379 | }
380 |
381 | fe_mul(t1, t2, t1);
382 | fe_sq(t2, t1);
383 |
384 | for (i = 1; i < 50; ++i) {
385 | fe_sq(t2, t2);
386 | }
387 |
388 | fe_mul(t2, t2, t1);
389 | fe_sq(t3, t2);
390 |
391 | for (i = 1; i < 100; ++i) {
392 | fe_sq(t3, t3);
393 | }
394 |
395 | fe_mul(t2, t3, t2);
396 | fe_sq(t2, t2);
397 |
398 | for (i = 1; i < 50; ++i) {
399 | fe_sq(t2, t2);
400 | }
401 |
402 | fe_mul(t1, t2, t1);
403 | fe_sq(t1, t1);
404 |
405 | for (i = 1; i < 5; ++i) {
406 | fe_sq(t1, t1);
407 | }
408 |
409 | fe_mul(out, t1, t0);
410 | }
411 |
412 | /*
413 | return 1 if f is in {1,3,5,...,q-2}
414 | return 0 if f is in {0,2,4,...,q-1}
415 |
416 | Preconditions:
417 | |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
418 | */
419 |
420 | int fe_isnegative(const fe f) {
421 | uint8_t s[32];
422 |
423 | fe_tobytes(s, f);
424 |
425 | return s[0] & 1;
426 | }
427 |
428 | /*
429 | return 1 if f == 0
430 | return 0 if f != 0
431 |
432 | Preconditions:
433 | |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
434 | */
435 |
436 | int fe_isnonzero(const fe f) {
437 | uint8_t s[32];
438 | uint8_t r;
439 |
440 | fe_tobytes(s, f);
441 | r = s[0];
442 |
443 | for (size_t i = 1; i < 32; ++i)
444 | r |= s[i];
445 |
446 | return r != 0;
447 | }
448 |
449 | /*
450 | h = f * g
451 | Can overlap h with f or g.
452 |
453 | Preconditions:
454 | |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
455 | |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
456 |
457 | Postconditions:
458 | |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
459 | */
460 |
461 | /*
462 | Notes on implementation strategy:
463 |
464 | Using schoolbook multiplication.
465 | Karatsuba would save a little in some cost models.
466 |
467 | Most multiplications by 2 and 19 are 32-bit precomputations;
468 | cheaper than 64-bit postcomputations.
469 |
470 | There is one remaining multiplication by 19 in the carry chain;
471 | one *19 precomputation can be merged into this,
472 | but the resulting data flow is considerably less clean.
473 |
474 | There are 12 carries below.
475 | 10 of them are 2-way parallelizable and vectorizable.
476 | Can get away with 11 carries, but then data flow is much deeper.
477 |
478 | With tighter constraints on inputs can squeeze carries into int32.
479 | */
480 |
481 | void fe_mul(fe h, const fe f, const fe g) {
482 | int32_t f0 = f[0];
483 | int32_t f1 = f[1];
484 | int32_t f2 = f[2];
485 | int32_t f3 = f[3];
486 | int32_t f4 = f[4];
487 | int32_t f5 = f[5];
488 | int32_t f6 = f[6];
489 | int32_t f7 = f[7];
490 | int32_t f8 = f[8];
491 | int32_t f9 = f[9];
492 | int32_t g0 = g[0];
493 | int32_t g1 = g[1];
494 | int32_t g2 = g[2];
495 | int32_t g3 = g[3];
496 | int32_t g4 = g[4];
497 | int32_t g5 = g[5];
498 | int32_t g6 = g[6];
499 | int32_t g7 = g[7];
500 | int32_t g8 = g[8];
501 | int32_t g9 = g[9];
502 | int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
503 | int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
504 | int32_t g3_19 = 19 * g3;
505 | int32_t g4_19 = 19 * g4;
506 | int32_t g5_19 = 19 * g5;
507 | int32_t g6_19 = 19 * g6;
508 | int32_t g7_19 = 19 * g7;
509 | int32_t g8_19 = 19 * g8;
510 | int32_t g9_19 = 19 * g9;
511 | int32_t f1_2 = 2 * f1;
512 | int32_t f3_2 = 2 * f3;
513 | int32_t f5_2 = 2 * f5;
514 | int32_t f7_2 = 2 * f7;
515 | int32_t f9_2 = 2 * f9;
516 | int64_t f0g0 = f0 * (int64_t)g0;
517 | int64_t f0g1 = f0 * (int64_t)g1;
518 | int64_t f0g2 = f0 * (int64_t)g2;
519 | int64_t f0g3 = f0 * (int64_t)g3;
520 | int64_t f0g4 = f0 * (int64_t)g4;
521 | int64_t f0g5 = f0 * (int64_t)g5;
522 | int64_t f0g6 = f0 * (int64_t)g6;
523 | int64_t f0g7 = f0 * (int64_t)g7;
524 | int64_t f0g8 = f0 * (int64_t)g8;
525 | int64_t f0g9 = f0 * (int64_t)g9;
526 | int64_t f1g0 = f1 * (int64_t)g0;
527 | int64_t f1g1_2 = f1_2 * (int64_t)g1;
528 | int64_t f1g2 = f1 * (int64_t)g2;
529 | int64_t f1g3_2 = f1_2 * (int64_t)g3;
530 | int64_t f1g4 = f1 * (int64_t)g4;
531 | int64_t f1g5_2 = f1_2 * (int64_t)g5;
532 | int64_t f1g6 = f1 * (int64_t)g6;
533 | int64_t f1g7_2 = f1_2 * (int64_t)g7;
534 | int64_t f1g8 = f1 * (int64_t)g8;
535 | int64_t f1g9_38 = f1_2 * (int64_t)g9_19;
536 | int64_t f2g0 = f2 * (int64_t)g0;
537 | int64_t f2g1 = f2 * (int64_t)g1;
538 | int64_t f2g2 = f2 * (int64_t)g2;
539 | int64_t f2g3 = f2 * (int64_t)g3;
540 | int64_t f2g4 = f2 * (int64_t)g4;
541 | int64_t f2g5 = f2 * (int64_t)g5;
542 | int64_t f2g6 = f2 * (int64_t)g6;
543 | int64_t f2g7 = f2 * (int64_t)g7;
544 | int64_t f2g8_19 = f2 * (int64_t)g8_19;
545 | int64_t f2g9_19 = f2 * (int64_t)g9_19;
546 | int64_t f3g0 = f3 * (int64_t)g0;
547 | int64_t f3g1_2 = f3_2 * (int64_t)g1;
548 | int64_t f3g2 = f3 * (int64_t)g2;
549 | int64_t f3g3_2 = f3_2 * (int64_t)g3;
550 | int64_t f3g4 = f3 * (int64_t)g4;
551 | int64_t f3g5_2 = f3_2 * (int64_t)g5;
552 | int64_t f3g6 = f3 * (int64_t)g6;
553 | int64_t f3g7_38 = f3_2 * (int64_t)g7_19;
554 | int64_t f3g8_19 = f3 * (int64_t)g8_19;
555 | int64_t f3g9_38 = f3_2 * (int64_t)g9_19;
556 | int64_t f4g0 = f4 * (int64_t)g0;
557 | int64_t f4g1 = f4 * (int64_t)g1;
558 | int64_t f4g2 = f4 * (int64_t)g2;
559 | int64_t f4g3 = f4 * (int64_t)g3;
560 | int64_t f4g4 = f4 * (int64_t)g4;
561 | int64_t f4g5 = f4 * (int64_t)g5;
562 | int64_t f4g6_19 = f4 * (int64_t)g6_19;
563 | int64_t f4g7_19 = f4 * (int64_t)g7_19;
564 | int64_t f4g8_19 = f4 * (int64_t)g8_19;
565 | int64_t f4g9_19 = f4 * (int64_t)g9_19;
566 | int64_t f5g0 = f5 * (int64_t)g0;
567 | int64_t f5g1_2 = f5_2 * (int64_t)g1;
568 | int64_t f5g2 = f5 * (int64_t)g2;
569 | int64_t f5g3_2 = f5_2 * (int64_t)g3;
570 | int64_t f5g4 = f5 * (int64_t)g4;
571 | int64_t f5g5_38 = f5_2 * (int64_t)g5_19;
572 | int64_t f5g6_19 = f5 * (int64_t)g6_19;
573 | int64_t f5g7_38 = f5_2 * (int64_t)g7_19;
574 | int64_t f5g8_19 = f5 * (int64_t)g8_19;
575 | int64_t f5g9_38 = f5_2 * (int64_t)g9_19;
576 | int64_t f6g0 = f6 * (int64_t)g0;
577 | int64_t f6g1 = f6 * (int64_t)g1;
578 | int64_t f6g2 = f6 * (int64_t)g2;
579 | int64_t f6g3 = f6 * (int64_t)g3;
580 | int64_t f6g4_19 = f6 * (int64_t)g4_19;
581 | int64_t f6g5_19 = f6 * (int64_t)g5_19;
582 | int64_t f6g6_19 = f6 * (int64_t)g6_19;
583 | int64_t f6g7_19 = f6 * (int64_t)g7_19;
584 | int64_t f6g8_19 = f6 * (int64_t)g8_19;
585 | int64_t f6g9_19 = f6 * (int64_t)g9_19;
586 | int64_t f7g0 = f7 * (int64_t)g0;
587 | int64_t f7g1_2 = f7_2 * (int64_t)g1;
588 | int64_t f7g2 = f7 * (int64_t)g2;
589 | int64_t f7g3_38 = f7_2 * (int64_t)g3_19;
590 | int64_t f7g4_19 = f7 * (int64_t)g4_19;
591 | int64_t f7g5_38 = f7_2 * (int64_t)g5_19;
592 | int64_t f7g6_19 = f7 * (int64_t)g6_19;
593 | int64_t f7g7_38 = f7_2 * (int64_t)g7_19;
594 | int64_t f7g8_19 = f7 * (int64_t)g8_19;
595 | int64_t f7g9_38 = f7_2 * (int64_t)g9_19;
596 | int64_t f8g0 = f8 * (int64_t)g0;
597 | int64_t f8g1 = f8 * (int64_t)g1;
598 | int64_t f8g2_19 = f8 * (int64_t)g2_19;
599 | int64_t f8g3_19 = f8 * (int64_t)g3_19;
600 | int64_t f8g4_19 = f8 * (int64_t)g4_19;
601 | int64_t f8g5_19 = f8 * (int64_t)g5_19;
602 | int64_t f8g6_19 = f8 * (int64_t)g6_19;
603 | int64_t f8g7_19 = f8 * (int64_t)g7_19;
604 | int64_t f8g8_19 = f8 * (int64_t)g8_19;
605 | int64_t f8g9_19 = f8 * (int64_t)g9_19;
606 | int64_t f9g0 = f9 * (int64_t)g0;
607 | int64_t f9g1_38 = f9_2 * (int64_t)g1_19;
608 | int64_t f9g2_19 = f9 * (int64_t)g2_19;
609 | int64_t f9g3_38 = f9_2 * (int64_t)g3_19;
610 | int64_t f9g4_19 = f9 * (int64_t)g4_19;
611 | int64_t f9g5_38 = f9_2 * (int64_t)g5_19;
612 | int64_t f9g6_19 = f9 * (int64_t)g6_19;
613 | int64_t f9g7_38 = f9_2 * (int64_t)g7_19;
614 | int64_t f9g8_19 = f9 * (int64_t)g8_19;
615 | int64_t f9g9_38 = f9_2 * (int64_t)g9_19;
616 | int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38;
617 | int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19;
618 | int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38;
619 | int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19;
620 | int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38;
621 | int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19;
622 | int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38;
623 | int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19;
624 | int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38;
625 | int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0;
626 | int64_t carry0;
627 | int64_t carry1;
628 | int64_t carry2;
629 | int64_t carry3;
630 | int64_t carry4;
631 | int64_t carry5;
632 | int64_t carry6;
633 | int64_t carry7;
634 | int64_t carry8;
635 | int64_t carry9;
636 |
637 | carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
638 | h1 += carry0;
639 | h0 -= carry0 << 26;
640 | carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
641 | h5 += carry4;
642 | h4 -= carry4 << 26;
643 |
644 | carry1 = (h1 + (int64_t)(1 << 24)) >> 25;
645 | h2 += carry1;
646 | h1 -= carry1 << 25;
647 | carry5 = (h5 + (int64_t)(1 << 24)) >> 25;
648 | h6 += carry5;
649 | h5 -= carry5 << 25;
650 |
651 | carry2 = (h2 + (int64_t)(1 << 25)) >> 26;
652 | h3 += carry2;
653 | h2 -= carry2 << 26;
654 | carry6 = (h6 + (int64_t)(1 << 25)) >> 26;
655 | h7 += carry6;
656 | h6 -= carry6 << 26;
657 |
658 | carry3 = (h3 + (int64_t)(1 << 24)) >> 25;
659 | h4 += carry3;
660 | h3 -= carry3 << 25;
661 | carry7 = (h7 + (int64_t)(1 << 24)) >> 25;
662 | h8 += carry7;
663 | h7 -= carry7 << 25;
664 |
665 | carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
666 | h5 += carry4;
667 | h4 -= carry4 << 26;
668 | carry8 = (h8 + (int64_t)(1 << 25)) >> 26;
669 | h9 += carry8;
670 | h8 -= carry8 << 26;
671 |
672 | carry9 = (h9 + (int64_t)(1 << 24)) >> 25;
673 | h0 += carry9 * 19;
674 | h9 -= carry9 << 25;
675 |
676 | carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
677 | h1 += carry0;
678 | h0 -= carry0 << 26;
679 |
680 | h[0] = (int32_t)h0;
681 | h[1] = (int32_t)h1;
682 | h[2] = (int32_t)h2;
683 | h[3] = (int32_t)h3;
684 | h[4] = (int32_t)h4;
685 | h[5] = (int32_t)h5;
686 | h[6] = (int32_t)h6;
687 | h[7] = (int32_t)h7;
688 | h[8] = (int32_t)h8;
689 | h[9] = (int32_t)h9;
690 | }
691 |
692 | /*
693 | h = f * 121666
694 | Can overlap h with f.
695 |
696 | Preconditions:
697 | |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
698 |
699 | Postconditions:
700 | |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
701 | */
702 |
703 | void fe_mul121666(fe h, fe f) {
704 | int32_t f0 = f[0];
705 | int32_t f1 = f[1];
706 | int32_t f2 = f[2];
707 | int32_t f3 = f[3];
708 | int32_t f4 = f[4];
709 | int32_t f5 = f[5];
710 | int32_t f6 = f[6];
711 | int32_t f7 = f[7];
712 | int32_t f8 = f[8];
713 | int32_t f9 = f[9];
714 | int64_t h0 = f0 * (int64_t)121666;
715 | int64_t h1 = f1 * (int64_t)121666;
716 | int64_t h2 = f2 * (int64_t)121666;
717 | int64_t h3 = f3 * (int64_t)121666;
718 | int64_t h4 = f4 * (int64_t)121666;
719 | int64_t h5 = f5 * (int64_t)121666;
720 | int64_t h6 = f6 * (int64_t)121666;
721 | int64_t h7 = f7 * (int64_t)121666;
722 | int64_t h8 = f8 * (int64_t)121666;
723 | int64_t h9 = f9 * (int64_t)121666;
724 | int64_t carry0;
725 | int64_t carry1;
726 | int64_t carry2;
727 | int64_t carry3;
728 | int64_t carry4;
729 | int64_t carry5;
730 | int64_t carry6;
731 | int64_t carry7;
732 | int64_t carry8;
733 | int64_t carry9;
734 |
735 | carry9 = (h9 + (int64_t)(1 << 24)) >> 25;
736 | h0 += carry9 * 19;
737 | h9 -= carry9 << 25;
738 | carry1 = (h1 + (int64_t)(1 << 24)) >> 25;
739 | h2 += carry1;
740 | h1 -= carry1 << 25;
741 | carry3 = (h3 + (int64_t)(1 << 24)) >> 25;
742 | h4 += carry3;
743 | h3 -= carry3 << 25;
744 | carry5 = (h5 + (int64_t)(1 << 24)) >> 25;
745 | h6 += carry5;
746 | h5 -= carry5 << 25;
747 | carry7 = (h7 + (int64_t)(1 << 24)) >> 25;
748 | h8 += carry7;
749 | h7 -= carry7 << 25;
750 |
751 | carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
752 | h1 += carry0;
753 | h0 -= carry0 << 26;
754 | carry2 = (h2 + (int64_t)(1 << 25)) >> 26;
755 | h3 += carry2;
756 | h2 -= carry2 << 26;
757 | carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
758 | h5 += carry4;
759 | h4 -= carry4 << 26;
760 | carry6 = (h6 + (int64_t)(1 << 25)) >> 26;
761 | h7 += carry6;
762 | h6 -= carry6 << 26;
763 | carry8 = (h8 + (int64_t)(1 << 25)) >> 26;
764 | h9 += carry8;
765 | h8 -= carry8 << 26;
766 |
767 | h[0] = (int32_t)h0;
768 | h[1] = (int32_t)h1;
769 | h[2] = (int32_t)h2;
770 | h[3] = (int32_t)h3;
771 | h[4] = (int32_t)h4;
772 | h[5] = (int32_t)h5;
773 | h[6] = (int32_t)h6;
774 | h[7] = (int32_t)h7;
775 | h[8] = (int32_t)h8;
776 | h[9] = (int32_t)h9;
777 | }
778 |
779 | /*
780 | h = -f
781 |
782 | Preconditions:
783 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
784 |
785 | Postconditions:
786 | |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
787 | */
788 |
789 | void fe_neg(fe h, const fe f) {
790 | int32_t f0 = f[0];
791 | int32_t f1 = f[1];
792 | int32_t f2 = f[2];
793 | int32_t f3 = f[3];
794 | int32_t f4 = f[4];
795 | int32_t f5 = f[5];
796 | int32_t f6 = f[6];
797 | int32_t f7 = f[7];
798 | int32_t f8 = f[8];
799 | int32_t f9 = f[9];
800 | int32_t h0 = -f0;
801 | int32_t h1 = -f1;
802 | int32_t h2 = -f2;
803 | int32_t h3 = -f3;
804 | int32_t h4 = -f4;
805 | int32_t h5 = -f5;
806 | int32_t h6 = -f6;
807 | int32_t h7 = -f7;
808 | int32_t h8 = -f8;
809 | int32_t h9 = -f9;
810 |
811 | h[0] = h0;
812 | h[1] = h1;
813 | h[2] = h2;
814 | h[3] = h3;
815 | h[4] = h4;
816 | h[5] = h5;
817 | h[6] = h6;
818 | h[7] = h7;
819 | h[8] = h8;
820 | h[9] = h9;
821 | }
822 |
823 | void fe_pow22523(fe out, const fe z) {
824 | fe t0;
825 | fe t1;
826 | fe t2;
827 | int i;
828 | fe_sq(t0, z);
829 |
830 | //for (i = 1; i < 1; ++i) {
831 | // fe_sq(t0, t0);
832 | //}
833 |
834 | fe_sq(t1, t0);
835 |
836 | for (i = 1; i < 2; ++i) {
837 | fe_sq(t1, t1);
838 | }
839 |
840 | fe_mul(t1, z, t1);
841 | fe_mul(t0, t0, t1);
842 | fe_sq(t0, t0);
843 |
844 | //for (i = 1; i < 1; ++i) {
845 | // fe_sq(t0, t0);
846 | //}
847 |
848 | fe_mul(t0, t1, t0);
849 | fe_sq(t1, t0);
850 |
851 | for (i = 1; i < 5; ++i) {
852 | fe_sq(t1, t1);
853 | }
854 |
855 | fe_mul(t0, t1, t0);
856 | fe_sq(t1, t0);
857 |
858 | for (i = 1; i < 10; ++i) {
859 | fe_sq(t1, t1);
860 | }
861 |
862 | fe_mul(t1, t1, t0);
863 | fe_sq(t2, t1);
864 |
865 | for (i = 1; i < 20; ++i) {
866 | fe_sq(t2, t2);
867 | }
868 |
869 | fe_mul(t1, t2, t1);
870 | fe_sq(t1, t1);
871 |
872 | for (i = 1; i < 10; ++i) {
873 | fe_sq(t1, t1);
874 | }
875 |
876 | fe_mul(t0, t1, t0);
877 | fe_sq(t1, t0);
878 |
879 | for (i = 1; i < 50; ++i) {
880 | fe_sq(t1, t1);
881 | }
882 |
883 | fe_mul(t1, t1, t0);
884 | fe_sq(t2, t1);
885 |
886 | for (i = 1; i < 100; ++i) {
887 | fe_sq(t2, t2);
888 | }
889 |
890 | fe_mul(t1, t2, t1);
891 | fe_sq(t1, t1);
892 |
893 | for (i = 1; i < 50; ++i) {
894 | fe_sq(t1, t1);
895 | }
896 |
897 | fe_mul(t0, t1, t0);
898 | fe_sq(t0, t0);
899 |
900 | for (i = 1; i < 2; ++i) {
901 | fe_sq(t0, t0);
902 | }
903 |
904 | fe_mul(out, t0, z);
905 | return;
906 | }
907 |
908 | /*
909 | h = f * f
910 | Can overlap h with f.
911 |
912 | Preconditions:
913 | |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
914 |
915 | Postconditions:
916 | |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
917 | */
918 |
919 | /*
920 | See fe_mul.c for discussion of implementation strategy.
921 | */
922 |
923 | void fe_sq(fe h, const fe f) {
924 | int32_t f0 = f[0];
925 | int32_t f1 = f[1];
926 | int32_t f2 = f[2];
927 | int32_t f3 = f[3];
928 | int32_t f4 = f[4];
929 | int32_t f5 = f[5];
930 | int32_t f6 = f[6];
931 | int32_t f7 = f[7];
932 | int32_t f8 = f[8];
933 | int32_t f9 = f[9];
934 | int32_t f0_2 = 2 * f0;
935 | int32_t f1_2 = 2 * f1;
936 | int32_t f2_2 = 2 * f2;
937 | int32_t f3_2 = 2 * f3;
938 | int32_t f4_2 = 2 * f4;
939 | int32_t f5_2 = 2 * f5;
940 | int32_t f6_2 = 2 * f6;
941 | int32_t f7_2 = 2 * f7;
942 | int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
943 | int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
944 | int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
945 | int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
946 | int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
947 | int64_t f0f0 = f0 * (int64_t)f0;
948 | int64_t f0f1_2 = f0_2 * (int64_t)f1;
949 | int64_t f0f2_2 = f0_2 * (int64_t)f2;
950 | int64_t f0f3_2 = f0_2 * (int64_t)f3;
951 | int64_t f0f4_2 = f0_2 * (int64_t)f4;
952 | int64_t f0f5_2 = f0_2 * (int64_t)f5;
953 | int64_t f0f6_2 = f0_2 * (int64_t)f6;
954 | int64_t f0f7_2 = f0_2 * (int64_t)f7;
955 | int64_t f0f8_2 = f0_2 * (int64_t)f8;
956 | int64_t f0f9_2 = f0_2 * (int64_t)f9;
957 | int64_t f1f1_2 = f1_2 * (int64_t)f1;
958 | int64_t f1f2_2 = f1_2 * (int64_t)f2;
959 | int64_t f1f3_4 = f1_2 * (int64_t)f3_2;
960 | int64_t f1f4_2 = f1_2 * (int64_t)f4;
961 | int64_t f1f5_4 = f1_2 * (int64_t)f5_2;
962 | int64_t f1f6_2 = f1_2 * (int64_t)f6;
963 | int64_t f1f7_4 = f1_2 * (int64_t)f7_2;
964 | int64_t f1f8_2 = f1_2 * (int64_t)f8;
965 | int64_t f1f9_76 = f1_2 * (int64_t)f9_38;
966 | int64_t f2f2 = f2 * (int64_t)f2;
967 | int64_t f2f3_2 = f2_2 * (int64_t)f3;
968 | int64_t f2f4_2 = f2_2 * (int64_t)f4;
969 | int64_t f2f5_2 = f2_2 * (int64_t)f5;
970 | int64_t f2f6_2 = f2_2 * (int64_t)f6;
971 | int64_t f2f7_2 = f2_2 * (int64_t)f7;
972 | int64_t f2f8_38 = f2_2 * (int64_t)f8_19;
973 | int64_t f2f9_38 = f2 * (int64_t)f9_38;
974 | int64_t f3f3_2 = f3_2 * (int64_t)f3;
975 | int64_t f3f4_2 = f3_2 * (int64_t)f4;
976 | int64_t f3f5_4 = f3_2 * (int64_t)f5_2;
977 | int64_t f3f6_2 = f3_2 * (int64_t)f6;
978 | int64_t f3f7_76 = f3_2 * (int64_t)f7_38;
979 | int64_t f3f8_38 = f3_2 * (int64_t)f8_19;
980 | int64_t f3f9_76 = f3_2 * (int64_t)f9_38;
981 | int64_t f4f4 = f4 * (int64_t)f4;
982 | int64_t f4f5_2 = f4_2 * (int64_t)f5;
983 | int64_t f4f6_38 = f4_2 * (int64_t)f6_19;
984 | int64_t f4f7_38 = f4 * (int64_t)f7_38;
985 | int64_t f4f8_38 = f4_2 * (int64_t)f8_19;
986 | int64_t f4f9_38 = f4 * (int64_t)f9_38;
987 | int64_t f5f5_38 = f5 * (int64_t)f5_38;
988 | int64_t f5f6_38 = f5_2 * (int64_t)f6_19;
989 | int64_t f5f7_76 = f5_2 * (int64_t)f7_38;
990 | int64_t f5f8_38 = f5_2 * (int64_t)f8_19;
991 | int64_t f5f9_76 = f5_2 * (int64_t)f9_38;
992 | int64_t f6f6_19 = f6 * (int64_t)f6_19;
993 | int64_t f6f7_38 = f6 * (int64_t)f7_38;
994 | int64_t f6f8_38 = f6_2 * (int64_t)f8_19;
995 | int64_t f6f9_38 = f6 * (int64_t)f9_38;
996 | int64_t f7f7_38 = f7 * (int64_t)f7_38;
997 | int64_t f7f8_38 = f7_2 * (int64_t)f8_19;
998 | int64_t f7f9_76 = f7_2 * (int64_t)f9_38;
999 | int64_t f8f8_19 = f8 * (int64_t)f8_19;
1000 | int64_t f8f9_38 = f8 * (int64_t)f9_38;
1001 | int64_t f9f9_38 = f9 * (int64_t)f9_38;
1002 | int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
1003 | int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
1004 | int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
1005 | int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
1006 | int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
1007 | int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
1008 | int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
1009 | int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
1010 | int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
1011 | int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
1012 | int64_t carry0;
1013 | int64_t carry1;
1014 | int64_t carry2;
1015 | int64_t carry3;
1016 | int64_t carry4;
1017 | int64_t carry5;
1018 | int64_t carry6;
1019 | int64_t carry7;
1020 | int64_t carry8;
1021 | int64_t carry9;
1022 | carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
1023 | h1 += carry0;
1024 | h0 -= carry0 << 26;
1025 | carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
1026 | h5 += carry4;
1027 | h4 -= carry4 << 26;
1028 | carry1 = (h1 + (int64_t)(1 << 24)) >> 25;
1029 | h2 += carry1;
1030 | h1 -= carry1 << 25;
1031 | carry5 = (h5 + (int64_t)(1 << 24)) >> 25;
1032 | h6 += carry5;
1033 | h5 -= carry5 << 25;
1034 | carry2 = (h2 + (int64_t)(1 << 25)) >> 26;
1035 | h3 += carry2;
1036 | h2 -= carry2 << 26;
1037 | carry6 = (h6 + (int64_t)(1 << 25)) >> 26;
1038 | h7 += carry6;
1039 | h6 -= carry6 << 26;
1040 | carry3 = (h3 + (int64_t)(1 << 24)) >> 25;
1041 | h4 += carry3;
1042 | h3 -= carry3 << 25;
1043 | carry7 = (h7 + (int64_t)(1 << 24)) >> 25;
1044 | h8 += carry7;
1045 | h7 -= carry7 << 25;
1046 | carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
1047 | h5 += carry4;
1048 | h4 -= carry4 << 26;
1049 | carry8 = (h8 + (int64_t)(1 << 25)) >> 26;
1050 | h9 += carry8;
1051 | h8 -= carry8 << 26;
1052 | carry9 = (h9 + (int64_t)(1 << 24)) >> 25;
1053 | h0 += carry9 * 19;
1054 | h9 -= carry9 << 25;
1055 | carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
1056 | h1 += carry0;
1057 | h0 -= carry0 << 26;
1058 | h[0] = (int32_t)h0;
1059 | h[1] = (int32_t)h1;
1060 | h[2] = (int32_t)h2;
1061 | h[3] = (int32_t)h3;
1062 | h[4] = (int32_t)h4;
1063 | h[5] = (int32_t)h5;
1064 | h[6] = (int32_t)h6;
1065 | h[7] = (int32_t)h7;
1066 | h[8] = (int32_t)h8;
1067 | h[9] = (int32_t)h9;
1068 | }
1069 |
1070 | /*
1071 | h = 2 * f * f
1072 | Can overlap h with f.
1073 |
1074 | Preconditions:
1075 | |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
1076 |
1077 | Postconditions:
1078 | |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
1079 | */
1080 |
1081 | /*
1082 | See fe_mul.c for discussion of implementation strategy.
1083 | */
1084 |
1085 | void fe_sq2(fe h, const fe f) {
1086 | int32_t f0 = f[0];
1087 | int32_t f1 = f[1];
1088 | int32_t f2 = f[2];
1089 | int32_t f3 = f[3];
1090 | int32_t f4 = f[4];
1091 | int32_t f5 = f[5];
1092 | int32_t f6 = f[6];
1093 | int32_t f7 = f[7];
1094 | int32_t f8 = f[8];
1095 | int32_t f9 = f[9];
1096 | int32_t f0_2 = 2 * f0;
1097 | int32_t f1_2 = 2 * f1;
1098 | int32_t f2_2 = 2 * f2;
1099 | int32_t f3_2 = 2 * f3;
1100 | int32_t f4_2 = 2 * f4;
1101 | int32_t f5_2 = 2 * f5;
1102 | int32_t f6_2 = 2 * f6;
1103 | int32_t f7_2 = 2 * f7;
1104 | int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
1105 | int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
1106 | int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
1107 | int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
1108 | int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
1109 | int64_t f0f0 = f0 * (int64_t)f0;
1110 | int64_t f0f1_2 = f0_2 * (int64_t)f1;
1111 | int64_t f0f2_2 = f0_2 * (int64_t)f2;
1112 | int64_t f0f3_2 = f0_2 * (int64_t)f3;
1113 | int64_t f0f4_2 = f0_2 * (int64_t)f4;
1114 | int64_t f0f5_2 = f0_2 * (int64_t)f5;
1115 | int64_t f0f6_2 = f0_2 * (int64_t)f6;
1116 | int64_t f0f7_2 = f0_2 * (int64_t)f7;
1117 | int64_t f0f8_2 = f0_2 * (int64_t)f8;
1118 | int64_t f0f9_2 = f0_2 * (int64_t)f9;
1119 | int64_t f1f1_2 = f1_2 * (int64_t)f1;
1120 | int64_t f1f2_2 = f1_2 * (int64_t)f2;
1121 | int64_t f1f3_4 = f1_2 * (int64_t)f3_2;
1122 | int64_t f1f4_2 = f1_2 * (int64_t)f4;
1123 | int64_t f1f5_4 = f1_2 * (int64_t)f5_2;
1124 | int64_t f1f6_2 = f1_2 * (int64_t)f6;
1125 | int64_t f1f7_4 = f1_2 * (int64_t)f7_2;
1126 | int64_t f1f8_2 = f1_2 * (int64_t)f8;
1127 | int64_t f1f9_76 = f1_2 * (int64_t)f9_38;
1128 | int64_t f2f2 = f2 * (int64_t)f2;
1129 | int64_t f2f3_2 = f2_2 * (int64_t)f3;
1130 | int64_t f2f4_2 = f2_2 * (int64_t)f4;
1131 | int64_t f2f5_2 = f2_2 * (int64_t)f5;
1132 | int64_t f2f6_2 = f2_2 * (int64_t)f6;
1133 | int64_t f2f7_2 = f2_2 * (int64_t)f7;
1134 | int64_t f2f8_38 = f2_2 * (int64_t)f8_19;
1135 | int64_t f2f9_38 = f2 * (int64_t)f9_38;
1136 | int64_t f3f3_2 = f3_2 * (int64_t)f3;
1137 | int64_t f3f4_2 = f3_2 * (int64_t)f4;
1138 | int64_t f3f5_4 = f3_2 * (int64_t)f5_2;
1139 | int64_t f3f6_2 = f3_2 * (int64_t)f6;
1140 | int64_t f3f7_76 = f3_2 * (int64_t)f7_38;
1141 | int64_t f3f8_38 = f3_2 * (int64_t)f8_19;
1142 | int64_t f3f9_76 = f3_2 * (int64_t)f9_38;
1143 | int64_t f4f4 = f4 * (int64_t)f4;
1144 | int64_t f4f5_2 = f4_2 * (int64_t)f5;
1145 | int64_t f4f6_38 = f4_2 * (int64_t)f6_19;
1146 | int64_t f4f7_38 = f4 * (int64_t)f7_38;
1147 | int64_t f4f8_38 = f4_2 * (int64_t)f8_19;
1148 | int64_t f4f9_38 = f4 * (int64_t)f9_38;
1149 | int64_t f5f5_38 = f5 * (int64_t)f5_38;
1150 | int64_t f5f6_38 = f5_2 * (int64_t)f6_19;
1151 | int64_t f5f7_76 = f5_2 * (int64_t)f7_38;
1152 | int64_t f5f8_38 = f5_2 * (int64_t)f8_19;
1153 | int64_t f5f9_76 = f5_2 * (int64_t)f9_38;
1154 | int64_t f6f6_19 = f6 * (int64_t)f6_19;
1155 | int64_t f6f7_38 = f6 * (int64_t)f7_38;
1156 | int64_t f6f8_38 = f6_2 * (int64_t)f8_19;
1157 | int64_t f6f9_38 = f6 * (int64_t)f9_38;
1158 | int64_t f7f7_38 = f7 * (int64_t)f7_38;
1159 | int64_t f7f8_38 = f7_2 * (int64_t)f8_19;
1160 | int64_t f7f9_76 = f7_2 * (int64_t)f9_38;
1161 | int64_t f8f8_19 = f8 * (int64_t)f8_19;
1162 | int64_t f8f9_38 = f8 * (int64_t)f9_38;
1163 | int64_t f9f9_38 = f9 * (int64_t)f9_38;
1164 | int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
1165 | int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
1166 | int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
1167 | int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
1168 | int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
1169 | int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
1170 | int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
1171 | int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
1172 | int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
1173 | int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
1174 | int64_t carry0;
1175 | int64_t carry1;
1176 | int64_t carry2;
1177 | int64_t carry3;
1178 | int64_t carry4;
1179 | int64_t carry5;
1180 | int64_t carry6;
1181 | int64_t carry7;
1182 | int64_t carry8;
1183 | int64_t carry9;
1184 | h0 += h0;
1185 | h1 += h1;
1186 | h2 += h2;
1187 | h3 += h3;
1188 | h4 += h4;
1189 | h5 += h5;
1190 | h6 += h6;
1191 | h7 += h7;
1192 | h8 += h8;
1193 | h9 += h9;
1194 | carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
1195 | h1 += carry0;
1196 | h0 -= carry0 << 26;
1197 | carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
1198 | h5 += carry4;
1199 | h4 -= carry4 << 26;
1200 | carry1 = (h1 + (int64_t)(1 << 24)) >> 25;
1201 | h2 += carry1;
1202 | h1 -= carry1 << 25;
1203 | carry5 = (h5 + (int64_t)(1 << 24)) >> 25;
1204 | h6 += carry5;
1205 | h5 -= carry5 << 25;
1206 | carry2 = (h2 + (int64_t)(1 << 25)) >> 26;
1207 | h3 += carry2;
1208 | h2 -= carry2 << 26;
1209 | carry6 = (h6 + (int64_t)(1 << 25)) >> 26;
1210 | h7 += carry6;
1211 | h6 -= carry6 << 26;
1212 | carry3 = (h3 + (int64_t)(1 << 24)) >> 25;
1213 | h4 += carry3;
1214 | h3 -= carry3 << 25;
1215 | carry7 = (h7 + (int64_t)(1 << 24)) >> 25;
1216 | h8 += carry7;
1217 | h7 -= carry7 << 25;
1218 | carry4 = (h4 + (int64_t)(1 << 25)) >> 26;
1219 | h5 += carry4;
1220 | h4 -= carry4 << 26;
1221 | carry8 = (h8 + (int64_t)(1 << 25)) >> 26;
1222 | h9 += carry8;
1223 | h8 -= carry8 << 26;
1224 | carry9 = (h9 + (int64_t)(1 << 24)) >> 25;
1225 | h0 += carry9 * 19;
1226 | h9 -= carry9 << 25;
1227 | carry0 = (h0 + (int64_t)(1 << 25)) >> 26;
1228 | h1 += carry0;
1229 | h0 -= carry0 << 26;
1230 | h[0] = (int32_t)h0;
1231 | h[1] = (int32_t)h1;
1232 | h[2] = (int32_t)h2;
1233 | h[3] = (int32_t)h3;
1234 | h[4] = (int32_t)h4;
1235 | h[5] = (int32_t)h5;
1236 | h[6] = (int32_t)h6;
1237 | h[7] = (int32_t)h7;
1238 | h[8] = (int32_t)h8;
1239 | h[9] = (int32_t)h9;
1240 | }
1241 |
1242 | /*
1243 | h = f - g
1244 | Can overlap h with f or g.
1245 |
1246 | Preconditions:
1247 | |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
1248 | |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
1249 |
1250 | Postconditions:
1251 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
1252 | */
1253 |
1254 | void fe_sub(fe h, const fe f, const fe g) {
1255 | int32_t f0 = f[0];
1256 | int32_t f1 = f[1];
1257 | int32_t f2 = f[2];
1258 | int32_t f3 = f[3];
1259 | int32_t f4 = f[4];
1260 | int32_t f5 = f[5];
1261 | int32_t f6 = f[6];
1262 | int32_t f7 = f[7];
1263 | int32_t f8 = f[8];
1264 | int32_t f9 = f[9];
1265 | int32_t g0 = g[0];
1266 | int32_t g1 = g[1];
1267 | int32_t g2 = g[2];
1268 | int32_t g3 = g[3];
1269 | int32_t g4 = g[4];
1270 | int32_t g5 = g[5];
1271 | int32_t g6 = g[6];
1272 | int32_t g7 = g[7];
1273 | int32_t g8 = g[8];
1274 | int32_t g9 = g[9];
1275 | int32_t h0 = f0 - g0;
1276 | int32_t h1 = f1 - g1;
1277 | int32_t h2 = f2 - g2;
1278 | int32_t h3 = f3 - g3;
1279 | int32_t h4 = f4 - g4;
1280 | int32_t h5 = f5 - g5;
1281 | int32_t h6 = f6 - g6;
1282 | int32_t h7 = f7 - g7;
1283 | int32_t h8 = f8 - g8;
1284 | int32_t h9 = f9 - g9;
1285 |
1286 | h[0] = h0;
1287 | h[1] = h1;
1288 | h[2] = h2;
1289 | h[3] = h3;
1290 | h[4] = h4;
1291 | h[5] = h5;
1292 | h[6] = h6;
1293 | h[7] = h7;
1294 | h[8] = h8;
1295 | h[9] = h9;
1296 | }
1297 |
1298 | /*
1299 | Preconditions:
1300 | |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
1301 |
1302 | Write p=2^255-19; q=floor(h/p).
1303 | Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
1304 |
1305 | Proof:
1306 | Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
1307 | Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
1308 |
1309 | Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
1310 | Then 0> 25;
1346 | q = (h0 + q) >> 26;
1347 | q = (h1 + q) >> 25;
1348 | q = (h2 + q) >> 26;
1349 | q = (h3 + q) >> 25;
1350 | q = (h4 + q) >> 26;
1351 | q = (h5 + q) >> 25;
1352 | q = (h6 + q) >> 26;
1353 | q = (h7 + q) >> 25;
1354 | q = (h8 + q) >> 26;
1355 | q = (h9 + q) >> 25;
1356 | /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
1357 | h0 += 19 * q;
1358 | /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
1359 | carry0 = h0 >> 26;
1360 | h1 += carry0;
1361 | h0 -= carry0 << 26;
1362 | carry1 = h1 >> 25;
1363 | h2 += carry1;
1364 | h1 -= carry1 << 25;
1365 | carry2 = h2 >> 26;
1366 | h3 += carry2;
1367 | h2 -= carry2 << 26;
1368 | carry3 = h3 >> 25;
1369 | h4 += carry3;
1370 | h3 -= carry3 << 25;
1371 | carry4 = h4 >> 26;
1372 | h5 += carry4;
1373 | h4 -= carry4 << 26;
1374 | carry5 = h5 >> 25;
1375 | h6 += carry5;
1376 | h5 -= carry5 << 25;
1377 | carry6 = h6 >> 26;
1378 | h7 += carry6;
1379 | h6 -= carry6 << 26;
1380 | carry7 = h7 >> 25;
1381 | h8 += carry7;
1382 | h7 -= carry7 << 25;
1383 | carry8 = h8 >> 26;
1384 | h9 += carry8;
1385 | h8 -= carry8 << 26;
1386 | carry9 = h9 >> 25;
1387 | h9 -= carry9 << 25;
1388 |
1389 | /* h10 = carry9 */
1390 | /*
1391 | Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
1392 | Have h0+...+2^230 h9 between 0 and 2^255-1;
1393 | evidently 2^255 h10-2^255 q = 0.
1394 | Goal: Output h0+...+2^230 h9.
1395 | */
1396 | s[0] = (uint8_t)(h0 >> 0);
1397 | s[1] = (uint8_t)(h0 >> 8);
1398 | s[2] = (uint8_t)(h0 >> 16);
1399 | s[3] = (uint8_t)((h0 >> 24) | (h1 << 2));
1400 | s[4] = (uint8_t)(h1 >> 6);
1401 | s[5] = (uint8_t)(h1 >> 14);
1402 | s[6] = (uint8_t)((h1 >> 22) | (h2 << 3));
1403 | s[7] = (uint8_t)(h2 >> 5);
1404 | s[8] = (uint8_t)(h2 >> 13);
1405 | s[9] = (uint8_t)((h2 >> 21) | (h3 << 5));
1406 | s[10] = (uint8_t)(h3 >> 3);
1407 | s[11] = (uint8_t)(h3 >> 11);
1408 | s[12] = (uint8_t)((h3 >> 19) | (h4 << 6));
1409 | s[13] = (uint8_t)(h4 >> 2);
1410 | s[14] = (uint8_t)(h4 >> 10);
1411 | s[15] = (uint8_t)(h4 >> 18);
1412 | s[16] = (uint8_t)(h5 >> 0);
1413 | s[17] = (uint8_t)(h5 >> 8);
1414 | s[18] = (uint8_t)(h5 >> 16);
1415 | s[19] = (uint8_t)((h5 >> 24) | (h6 << 1));
1416 | s[20] = (uint8_t)(h6 >> 7);
1417 | s[21] = (uint8_t)(h6 >> 15);
1418 | s[22] = (uint8_t)((h6 >> 23) | (h7 << 3));
1419 | s[23] = (uint8_t)(h7 >> 5);
1420 | s[24] = (uint8_t)(h7 >> 13);
1421 | s[25] = (uint8_t)((h7 >> 21) | (h8 << 4));
1422 | s[26] = (uint8_t)(h8 >> 4);
1423 | s[27] = (uint8_t)(h8 >> 12);
1424 | s[28] = (uint8_t)((h8 >> 20) | (h9 << 6));
1425 | s[29] = (uint8_t)(h9 >> 2);
1426 | s[30] = (uint8_t)(h9 >> 10);
1427 | s[31] = (uint8_t)(h9 >> 18);
1428 | }
1429 |
--------------------------------------------------------------------------------