Skip to content

Instantly share code, notes, and snippets.

@SK0M0R0H
Created June 26, 2017 10:11
Show Gist options
  • Save SK0M0R0H/de0e94b84e9aea7d82314b44e2c03d1f to your computer and use it in GitHub Desktop.
Save SK0M0R0H/de0e94b84e9aea7d82314b44e2c03d1f to your computer and use it in GitHub Desktop.
pragma solidity 0.4.11;
contract DetENDSA
{
//Point of ellipcit curve
struct Point
{
uint256 x;
uint256 y;
}
uint256 q;
uint256 a; //y^2=x^3+ax+b - elliptic curve
Point G;
uint256 secretKey;
Point publicKey;
function setQ(uint256 _q)
{
q = _q;
}
function setCurvePoint(uint256 x, uint256 y)
{
G.x = x;
G.y = y;
}
function setA(uint256 _a)
{
a = _a;
}
function setSK(uint256 _secretKey)
{
secretKey = _secretKey;
}
function GeneratePublicKey()
{
publicKey = pointMultiplication(secretKey, G);
}
//Generation of the signature
function SignGeneration(string message) returns (uint256, uint256)
{
//Find hash of message
uint256 hashM = (uint256)(keccak256(message)) % q;
uint256 k = getK() % q; //random value
uint256 inverseK = inverseModulo(k, q);
uint256 r = (pointMultiplication(k, G)).x % q;
uint256 s = mulmod(addmod(hashM, mulmod(secretKey, r, q), q), inverseK, q);
return (r, s);
}
//Verification of signature (r,s)
function SignVerify(uint256 r, uint256 s, string message) returns (bool)
{
//Check that (r,s) is inegers from [1,q-1]
if (r<1 || r>q-1 || s<1 || s>q-1)
return false;
//Find hash of message
uint256 hashM = (uint256)(keccak256(message)) % q;
uint256 inverseS = inverseModulo(s, q);
uint256 u1 = mulmod(inverseS, hashM, q);
uint256 u2 = mulmod(inverseS, r, q);
uint256 v = (pointAddition(pointMultiplication(u1, G), pointMultiplication(u2, publicKey))).x % q;
return (v == r);
}
//The function in developing.
function getK() private returns (uint256)
{
return 10;
}
//return num mod modulo. Based on Euclid Algo
function inverseModulo(uint256 num, uint256 modulo) returns (uint256)
{
if (num == 0 || num == modulo || modulo == 0)
throw;
if (num > modulo)
num = num % modulo;
int256 t1;
int256 t2 = 1;
uint256 r1 = modulo;
uint256 r2 = num;
uint256 q;
while (r2 != 0) {
q = r1 / r2;
(t1, t2, r1, r2) = (t2, t1 - int(q) * t2, r2, r1 - q * r2);
}
if (t1 < 0)
return (modulo - uint(-t1));
return uint(t1);
}
//debugging function
function pointMul(uint256 n, uint256 Px, uint256 Py) returns (uint256, uint256)
{
Point memory np;
np.x = Px;
np.y = Py;
np = pointMultiplication(n, np);
return (np.x, np.y);
}
//debugging function
function pointAdd(uint256 Px, uint256 Py, uint256 Qx, uint256 Qy) returns (uint256, uint256)
{
Point memory np;
np.x = Px;
np.y = Py;
Point memory nq;
nq.x = Qx;
nq.y = Qy;
np = pointAddition(np, nq);
return (np.x, np.y);
}
//return n*P where P - point of the ellipttc curve, n - positive integer
function pointMultiplication(uint256 n, Point P) private returns (Point)
{
Point memory newPoint;
Point memory auxiliaryPoint;
newPoint.x = 0;
newPoint.y = 0;
auxiliaryPoint.x = P.x;
auxiliaryPoint.y = P.y;
//Analogue of the exponentiation by squaring for elliptic curves
for (int bit=0; bit<=256; bit++)
{
if ((n>>bit)&1 == 1)
{
newPoint = pointAddition(newPoint, auxiliaryPoint);
}
auxiliaryPoint = pointDoubling(auxiliaryPoint);
}
return newPoint;
}
//return P+Q where P,Q - points of the ellipttc curve
function pointAddition(Point P, Point Q) private returns (Point)
{
Point memory newPoint;
if (P.x == Q.x && P.y == Q.y)
return pointDoubling(P);
//alpha = (y2-y1)/(x2-x1)
uint256 alpha = mulmod(addmod(Q.y, q - P.y, q), inverseModulo(addmod(Q.x, q - P.x, q), q), q);
//x3 = a^2-x1-x2
newPoint.x = addmod(addmod(mulmod(alpha, alpha, q),-P.x + q, q), -Q.x + q, q);
//y3 = -y1+a*(x1-x3)
newPoint.y = addmod(mulmod(addmod(P.x, -newPoint.x + q, q), alpha, q), -P.y+q, q);
return newPoint;
}
//return 2*P = P+P where P - point of the ellipttc curve
function pointDoubling(Point P) private returns (Point)
{
Point memory newPoint;
//alpha = ((3*x1*x1)+a)/2y1
uint256 alpha = mulmod(addmod(mulmod(3, mulmod(P.x, P.x, q), q), a, q),inverseModulo(mulmod(2, P.y, q), q),q);
//x3 = alpha*alpha - 2x1
newPoint.x = addmod(mulmod(alpha, alpha, q), q - mulmod(2, P.x, q), q);
//y2 = alpha*(x1-x3)-y1
newPoint.y = addmod(mulmod(alpha, addmod(P.x, q - newPoint.x, q), q), q - P.y, q);
return newPoint;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment