00001
#ifndef CRYPTOPP_ECP_H
00002
#define CRYPTOPP_ECP_H
00003
00004
#include "modarith.h"
00005
#include "eprecomp.h"
00006
#include "smartptr.h"
00007
#include "pubkey.h"
00008
00009 NAMESPACE_BEGIN(CryptoPP)
00010
00011
00012 struct CRYPTOPP_DLL
ECPPoint
00013 {
00014 ECPPoint() : identity(
true) {}
00015 ECPPoint(
const Integer &x,
const Integer &y)
00016 : identity(
false), x(x), y(y) {}
00017
00018
bool operator==(
const ECPPoint &t)
const
00019
{
return (identity && t.identity) || (!identity && !t.identity && x==t.x && y==t.y);}
00020
bool operator< (
const ECPPoint &t)
const
00021
{
return identity ? !t.identity : (!t.identity && (x<t.x || (x==t.x && y<t.y)));}
00022
00023
bool identity;
00024
Integer x, y;
00025 };
00026
00027 CRYPTOPP_DLL_TEMPLATE_CLASS
AbstractGroup<ECPPoint>;
00028
00029
00030 class CRYPTOPP_DLL ECP :
public AbstractGroup<ECPPoint>
00031 {
00032
public:
00033
typedef ModularArithmetic Field;
00034
typedef Integer FieldElement;
00035
typedef ECPPoint Point;
00036
00037 ECP() {}
00038 ECP(
const ECP &ecp,
bool convertToMontgomeryRepresentation =
false);
00039 ECP(
const Integer &modulus,
const FieldElement &a,
const FieldElement &b)
00040 : m_fieldPtr(
new Field(modulus)), m_a(a.IsNegative() ? modulus+a : a), m_b(b) {}
00041
00042
00043 ECP(
BufferedTransformation &bt);
00044
00045
00046
void DEREncode(
BufferedTransformation &bt)
const;
00047
00048
bool Equal(
const Point &P,
const Point &Q)
const;
00049
const Point& Identity()
const;
00050
const Point& Inverse(
const Point &P)
const;
00051
bool InversionIsFast()
const {
return true;}
00052
const Point& Add(
const Point &P,
const Point &Q)
const;
00053
const Point& Double(
const Point &P)
const;
00054
Point ScalarMultiply(
const Point &P,
const Integer &k)
const;
00055
Point CascadeScalarMultiply(
const Point &P,
const Integer &k1,
const Point &Q,
const Integer &k2)
const;
00056
void SimultaneousMultiply(
Point *results,
const Point &base,
const Integer *exponents,
unsigned int exponentsCount)
const;
00057
00058
Point Multiply(
const Integer &k,
const Point &P)
const
00059
{
return ScalarMultiply(P, k);}
00060
Point CascadeMultiply(
const Integer &k1,
const Point &P,
const Integer &k2,
const Point &Q)
const
00061
{
return CascadeScalarMultiply(P, k1, Q, k2);}
00062
00063
bool ValidateParameters(
RandomNumberGenerator &rng,
unsigned int level=3)
const;
00064
bool VerifyPoint(
const Point &P)
const;
00065
00066
unsigned int EncodedPointSize(
bool compressed =
false)
const
00067
{
return 1 + (compressed?1:2)*GetField().MaxElementByteLength();}
00068
00069
bool DecodePoint(
Point &P,
BufferedTransformation &bt,
unsigned int len)
const;
00070
bool DecodePoint(
Point &P,
const byte *encodedPoint,
unsigned int len)
const;
00071
void EncodePoint(byte *encodedPoint,
const Point &P,
bool compressed)
const;
00072
void EncodePoint(
BufferedTransformation &bt,
const Point &P,
bool compressed)
const;
00073
00074
Point BERDecodePoint(
BufferedTransformation &bt)
const;
00075
void DEREncodePoint(
BufferedTransformation &bt,
const Point &P,
bool compressed)
const;
00076
00077
Integer FieldSize()
const {
return GetField().GetModulus();}
00078
const Field & GetField()
const {
return *m_fieldPtr;}
00079
const FieldElement & GetA()
const {
return m_a;}
00080
const FieldElement & GetB()
const {
return m_b;}
00081
00082
bool operator==(
const ECP &rhs)
const
00083
{
return GetField() == rhs.
GetField() && m_a == rhs.
m_a && m_b == rhs.
m_b;}
00084
00085
private:
00086 clonable_ptr<Field> m_fieldPtr;
00087
FieldElement m_a, m_b;
00088
mutable Point m_R;
00089 };
00090
00091 CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl<ECP::Point>;
00092 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation<ECP::Point>;
00093
00094
template <
class T>
class EcPrecomputation;
00095
00096
00097 template<>
class EcPrecomputation<ECP> :
public DL_GroupPrecomputation<ECP::Point>
00098 {
00099
public:
00100
typedef ECP
EllipticCurve;
00101
00102
00103
bool NeedConversions()
const {
return true;}
00104 Element ConvertIn(
const Element &P)
const
00105
{
return P.identity ? P :
ECP::Point(m_ec->GetField().ConvertIn(P.x), m_ec->GetField().ConvertIn(P.y));};
00106 Element ConvertOut(
const Element &P)
const
00107
{
return P.identity ? P :
ECP::Point(m_ec->GetField().ConvertOut(P.x), m_ec->GetField().ConvertOut(P.y));}
00108
const AbstractGroup<Element> & GetGroup()
const {
return *m_ec;}
00109 Element BERDecodeElement(
BufferedTransformation &bt)
const {
return m_ec->BERDecodePoint(bt);}
00110
void DEREncodeElement(
BufferedTransformation &bt,
const Element &v)
const {m_ec->DEREncodePoint(bt, v,
false);}
00111
00112
00113
void SetCurve(
const ECP &ec)
00114 {
00115 m_ec.reset(
new ECP(ec,
true));
00116 m_ecOriginal = ec;
00117 }
00118
const ECP & GetCurve()
const {
return *m_ecOriginal;}
00119
00120
private:
00121 value_ptr<ECP> m_ec, m_ecOriginal;
00122 };
00123
00124 NAMESPACE_END
00125
00126
#endif