2023-06-16 22:38:10 +03:00
|
|
|
/**
|
2023-06-17 00:58:22 +03:00
|
|
|
* This file is a part of the UMSKT Project
|
2023-06-16 22:38:10 +03:00
|
|
|
*
|
2023-06-17 00:58:22 +03:00
|
|
|
* Copyleft (C) 2019-2023 UMSKT Contributors (et.al.)
|
2023-06-16 22:38:10 +03:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* @FileCreated by Andrew on 01/06/2023
|
|
|
|
* @Maintainer Andrew
|
|
|
|
*/
|
2023-06-01 16:09:22 +03:00
|
|
|
|
2023-07-09 06:08:43 +03:00
|
|
|
#include "PIDGEN3.h"
|
2023-06-01 16:09:22 +03:00
|
|
|
|
2023-06-01 23:09:44 +03:00
|
|
|
int randomRange() {
|
2023-06-02 07:25:43 +03:00
|
|
|
return 4; // chosen by fair dice roll
|
|
|
|
// guaranteed to be random
|
2023-06-01 23:09:44 +03:00
|
|
|
}
|
|
|
|
|
2023-06-01 16:09:22 +03:00
|
|
|
/* Convert data between endianness types. */
|
2023-07-09 06:08:43 +03:00
|
|
|
void PIDGEN3::endian(BYTE *data, int length) {
|
2023-06-01 16:09:22 +03:00
|
|
|
for (int i = 0; i < length / 2; i++) {
|
2023-06-04 13:31:24 +03:00
|
|
|
BYTE temp = data[i];
|
2023-06-01 16:09:22 +03:00
|
|
|
data[i] = data[length - i - 1];
|
|
|
|
data[length - i - 1] = temp;
|
|
|
|
}
|
|
|
|
}
|
2023-06-01 22:19:35 +03:00
|
|
|
|
|
|
|
/* Initializes the elliptic curve. */
|
2023-07-09 06:08:43 +03:00
|
|
|
EC_GROUP* PIDGEN3::initializeEllipticCurve(
|
2023-06-02 07:25:43 +03:00
|
|
|
const std::string pSel,
|
|
|
|
const std::string aSel,
|
|
|
|
const std::string bSel,
|
|
|
|
const std::string generatorXSel,
|
|
|
|
const std::string generatorYSel,
|
|
|
|
const std::string publicKeyXSel,
|
|
|
|
const std::string publicKeyYSel,
|
2023-06-04 14:54:22 +03:00
|
|
|
EC_POINT *&genPoint,
|
|
|
|
EC_POINT *&pubPoint
|
2023-06-01 22:19:35 +03:00
|
|
|
) {
|
|
|
|
// Initialize BIGNUM and BIGNUMCTX structures.
|
|
|
|
// BIGNUM - Large numbers
|
|
|
|
// BIGNUMCTX - Context large numbers (temporary)
|
|
|
|
BIGNUM *a, *b, *p, *generatorX, *generatorY, *publicKeyX, *publicKeyY;
|
|
|
|
BN_CTX *context;
|
|
|
|
|
|
|
|
// We're presented with an elliptic curve, a multivariable function y(x; p; a; b), where
|
|
|
|
// y^2 % p = x^3 + ax + b % p.
|
|
|
|
a = BN_new();
|
|
|
|
b = BN_new();
|
|
|
|
p = BN_new();
|
|
|
|
|
|
|
|
// Public key will consist of the resulting (x; y) values.
|
|
|
|
publicKeyX = BN_new();
|
|
|
|
publicKeyY = BN_new();
|
|
|
|
|
|
|
|
// G(x; y) is a generator function, its return value represents a point on the elliptic curve.
|
|
|
|
generatorX = BN_new();
|
|
|
|
generatorY = BN_new();
|
|
|
|
|
|
|
|
// Context variable
|
|
|
|
context = BN_CTX_new();
|
|
|
|
|
|
|
|
/* Public data */
|
2023-06-02 07:25:43 +03:00
|
|
|
BN_dec2bn(&p, pSel.c_str());
|
|
|
|
BN_dec2bn(&a, aSel.c_str());
|
|
|
|
BN_dec2bn(&b, bSel.c_str());
|
|
|
|
BN_dec2bn(&generatorX, generatorXSel.c_str());
|
|
|
|
BN_dec2bn(&generatorY, generatorYSel.c_str());
|
2023-06-01 22:19:35 +03:00
|
|
|
|
2023-06-02 07:25:43 +03:00
|
|
|
BN_dec2bn(&publicKeyX, publicKeyXSel.c_str());
|
|
|
|
BN_dec2bn(&publicKeyY, publicKeyYSel.c_str());
|
2023-06-01 22:19:35 +03:00
|
|
|
|
|
|
|
/* Elliptic Curve calculations. */
|
|
|
|
// The group is defined via Fp = all integers [0; p - 1], where p is prime.
|
|
|
|
// The function EC_POINT_set_affine_coordinates() sets the x and y coordinates for the point p defined over the curve given in group.
|
|
|
|
EC_GROUP *eCurve = EC_GROUP_new_curve_GFp(p, a, b, context);
|
|
|
|
|
|
|
|
// Create new point for the generator on the elliptic curve and set its coordinates to (genX; genY).
|
2023-06-04 14:54:22 +03:00
|
|
|
genPoint = EC_POINT_new(eCurve);
|
|
|
|
EC_POINT_set_affine_coordinates(eCurve, genPoint, generatorX, generatorY, context);
|
2023-06-01 22:19:35 +03:00
|
|
|
|
|
|
|
// Create new point for the public key on the elliptic curve and set its coordinates to (pubX; pubY).
|
2023-06-04 14:54:22 +03:00
|
|
|
pubPoint = EC_POINT_new(eCurve);
|
|
|
|
EC_POINT_set_affine_coordinates(eCurve, pubPoint, publicKeyX, publicKeyY, context);
|
2023-06-01 22:19:35 +03:00
|
|
|
|
|
|
|
// If generator and public key points are not on the elliptic curve, either the generator or the public key values are incorrect.
|
2023-06-04 14:54:22 +03:00
|
|
|
assert(EC_POINT_is_on_curve(eCurve, genPoint, context) == true);
|
|
|
|
assert(EC_POINT_is_on_curve(eCurve, pubPoint, context) == true);
|
2023-06-01 22:19:35 +03:00
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
BN_CTX_free(context);
|
|
|
|
|
|
|
|
return eCurve;
|
2023-06-04 22:01:09 +03:00
|
|
|
}
|
|
|
|
|
2023-07-09 06:08:43 +03:00
|
|
|
int PIDGEN3::BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen) {
|
2023-06-04 22:01:09 +03:00
|
|
|
if (a == nullptr || to == nullptr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
int len = BN_bn2bin(a, to);
|
|
|
|
|
|
|
|
if (len > tolen)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
// Choke point inside BN_bn2lebinpad: OpenSSL uses len instead of tolen.
|
|
|
|
endian(to, tolen);
|
|
|
|
|
|
|
|
return len;
|
2023-07-09 06:08:43 +03:00
|
|
|
}
|