Created
June 26, 2017 10:11
-
-
Save SK0M0R0H/de0e94b84e9aea7d82314b44e2c03d1f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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