2018年11月24日 星期六

用 C++ 運算 ECC, 學習 class 的運作

#include "gmp.h"
#include "stdio.h"
#include "stdarg.h"
typedef unsigned long int ulongint;
class Curve383187{// Curve383187::  y2 = x3 + 229969 * x2 + x  mod p
    private: static const BigInteger p;// divider for modulus number is a prime number, it is a bitInt. p = 2383 - 187
    struct modNumber : BigInteger {// class extend from BigInteger, re-define operator + - * / ^ for modulus operation
        modNumber()                          : BigInteger( ) { }
        modNumber(const BigInteger &num)  : BigInteger(num.z) { }// convert BigInteger to modNumber
        modNumber(const char *s, int b=10): BigInteger(s, b) { }// default base 10 is convenient for ECC
        modNumber operator + (modNumber a) { return add(a).mod(p);              }
        modNumber operator - (modNumber a) { return sub(a).mod(p);              }
        modNumber operator * (modNumber a) { return mul(a).mod(p);              }
        modNumber operator / (modNumber a) { return mul(a.modinv(p)).mod(p); }
        modNumber operator ^ (ulongint  e) { return pwr(e).mod(p);              }
        modNumber operator * (ulongint  e) { return mul(e).mod(p);              }
      };
    modNumber a, b, x, y;
    public :   
    Curve383187(BigInteger key = BigInteger("1")) {// key is a scalar
        a = modNumber("229969");
        b = modNumber("1");
        x = modNumber("5");
        y = modNumber("4759238150142744228328102229734187233490253962521130945928672202662038422584867624507245060283757321006861735839455");
        if( key !=  1 )    scale(modNumber(key));   
     }
    bool isPoint()   { return (y^2) == ((x^3) + a*(x^2) + b*x); }
    void listpoint() {
        if( isPoint() )  printf("Yes\n");
        else             printf("No!\n");
        x.printf("\tx=").toHex();
        y.printf("\ty=").toHex();
     }
    Curve383187 operator + (Curve383187 ca)    {
         auto copy = *this;            // copy of this
         return copy.selfadd(ca);
     }
    Curve383187  operator * (modNumber n)          {
        auto copy = *this;      // copy of this
        return copy.scale(n); // return new object
     }
    Curve383187& selfadd(Curve383187 g)     { // R = P + Q
        auto s  = (y - g.y)/(x - g.x); // slope = (y - Gy)/(x - Gx)
        x = (s^2) - x - g.x - a;       // x = s2 - x - Gx - a
        y = s*(g.x - x) - g.y;             // y = s*(Gx - x) - Gy
        return *this; // return c object
     }  
    Curve383187& scale(modNumber num) {
        int k = 1024;    // number of bits
        if (num ==  0) { printf("Error, scale num is 0"); return *this;  }
        while (k-- > 0)  if (num.testBit(k))  break;// scan to MSB
        auto gx = x; 
        auto gy = y;
        while (k-- > 0){// Double And Add algorithm to scale G(x,y)  
            // Doubler slope = ( 3x2 + 2ax + b)/(2y)            
            auto px = x;                // save x to caculate y  
            auto s  = ((x^2)*3 + a*x*2 + b)/(y*2);   
            x = (s^2) - x*2 - a;         // x = s2 - 2x - a
            y = s*(px - x) - y;         // y = s * (px - x) - py 
            if (num.testBit(k)) {         // Adder slope = (y - Gy)/(x-Gx)
                s = (y - gy)/(x - gx);    // slope = (y - Gy)/(x - Gx)
                x = (s^2) - x - gx - a; // x = s2 - x - Gx - a
                y = s*(gx - x) - gy;      // y = s*(Gx - x) - Gy
              }   
        }
        return *this; // return self object
     }
 };
const BigInteger Curve383187 :: p = (BigInteger("2",10)^383) - BigInteger("187",10); // static member must be init outside

int main(){
    auto keyA  = (BigInteger("9",10)^87) - BigInteger("65",10); // Alice pickup a key
    auto keyB  = (BigInteger("4")^32)    - BigInteger("10",10); // Bob pickup a key
    auto key   = keyA*keyB;         // share key nobody knowns
    auto pubA  = Curve383187(keyA); // Alice send public key to Bob
    auto pubB  = Curve383187(keyB); // Bob send public key to Alice
    auto keyECC= Curve383187(key);  // Caculate the ECC of the secret to double check
    auto Alice = pubB * keyA;       // Alice use self key to decode pubB sent from Bob
    auto Bob   = pubA * keyB;       // Bob use self key to decode pubA sent from Alice  
    keyECC.listpoint();               // should be the same;
    Alice.listpoint() ;                // Alice decode
    Bob.listpoint()   ;                // Bob decode
}
運算結果:
Yes
    x=0x381dcd3a1bdea34760212d276c7d21940d315a4d547af3c520aba80a2ff4e38e0e548dd9d0038c1ce5c3eb36acf6960b
    y=0x3491be994e90f4e9b28352b5c0495c5f395dba99fe2fa870553351be77e363c67392e3c3feb2fed711b5d187c63afbbb
Yes
    x=0x381dcd3a1bdea34760212d276c7d21940d315a4d547af3c520aba80a2ff4e38e0e548dd9d0038c1ce5c3eb36acf6960b
    y=0x3491be994e90f4e9b28352b5c0495c5f395dba99fe2fa870553351be77e363c67392e3c3feb2fed711b5d187c63afbbb
Yes
    x=0x381dcd3a1bdea34760212d276c7d21940d315a4d547af3c520aba80a2ff4e38e0e548dd9d0038c1ce5c3eb36acf6960b
    y=0x3491be994e90f4e9b28352b5c0495c5f395dba99fe2fa870553351be77e363c67392e3c3feb2fed711b5d187c63afbbb

沒有留言: