/* 
   borZoi - An Elliptic Curve Cryptography Library

   Copyright (C) 2001 Anthony Mulcahy

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  

*/


#include <iostream>
#include <string>
#include <vector>
#include "borzoi_math.h"


#ifndef BORZOI_UTIL_H
#define BORZOI_UTIL_H

typedef unsigned char OCTET;
typedef std::vector<OCTET> OCTETSTR;


class borzoiException {
	std::string err_str;
public:
	inline borzoiException () {err_str="borzoiException";}
	inline borzoiException (std::string s) {err_str="borzoiException"+s;}
	inline void debug_print () {std::cerr << err_str.c_str() << std::endl;}
};

class Point {
public:
	F2M x;
	F2M y;
	inline Point () {}
	inline Point (F2M p_x, F2M p_y) { x = p_x; y = p_y; }
	inline Point (std::string p_x, std::string p_y) {str_to_F2M(p_x,x); str_to_F2M(p_y,y); }
	Point negative ();
	inline long isZero () {return (x.isZero () & y.isZero ());}
	std::ostream& put (std::ostream&s);
	Point& operator= (const Point& p);
};

inline bool operator== (Point a, Point b) {return (((a.x==b.x)&(a.y==b.y))>0);}

inline std::ostream& operator<< (std::ostream&s, Point p) { return p.put (s); }


// Elliptic Curve of form Y^2 + XY = x^3 + a2x^2 + a6 over F2M
class Curve {
public:
	F2M a2;
	F2M a6;
	inline Curve () {}
	inline Curve (F2M a2_val, F2M a6_val) { a2 = a2_val; a6 = a6_val; }
	inline Curve (std::string a2_val, std::string a6_val) { str_to_F2M (a2_val, a2); str_to_F2M (a6_val, a6); }
	std::ostream& put (std::ostream&s);
	Point add (Point p1, Point p2);
	Point dbl (Point p1);
	inline Point sub (Point p1, Point p2) {return add (p1,p2.negative());}
	Point mul (BigInt k, Point P);
};

inline std::ostream& operator<< (std::ostream&s, Curve c) { return c.put (s); }


// Conversion Functions
OCTETSTR BS2OSP (F2M b);

inline OCTETSTR FE2OSP (F2M x) { return BS2OSP (x); }

BigInt OS2IP (OCTETSTR o);

OCTETSTR I2OSP (BigInt i);

inline BigInt FE2IP (F2M j) { return OS2IP (FE2OSP(j)); }

F2M I2FEP (BigInt z); //FIXME may need to be replaced by the P1363 spec primitives


BigInt operator|| (const BigInt& a, const BigInt& b); // concantenate two BigInts
std::vector<OCTET> operator|| (const std::vector<OCTET>& a, const std::vector<OCTET>& b); // concantenate two OCTETSTR

std::vector<OCTET> operator^ (std::vector<OCTET> a, std::vector<OCTET> b); // xor two OCTETSTR


#endif	// BORZOI_UTIL_H
