Files
ANSCORE/core/anslicensing/ec2m.h

257 lines
5.8 KiB
C
Raw Normal View History

2026-03-28 16:54:11 +11:00
// elliptic curves over GF(2^(L*K))
#pragma once
#define MAXL 16
#define MAXK 193
class field;
class field_element;
class curve;
class full_curve_parameter;
class small_field
{
friend class field;
#if MAXL > 16 // assumes that unsigned short is at least 16 bits
typedef unsigned lunit;
#else
#if MAXL > 8
typedef unsigned short lunit;
#else
typedef unsigned char lunit;
#endif
#endif
// construction
public:
small_field( unsigned L, unsigned root );
~small_field();
// methods
public:
unsigned * curve_order();
// properties
public:
lunit * const alog; // index range is [0..(BASE-2)]
lunit * const log; // index range is [1..(BASE-1)], but log[0] is set to (BASE-1)
const unsigned L, BASE, BASE_M1;
};
// elements are polynomials with coefficients in small_field
class field : public small_field
{
friend class curve;
friend class field_element;
friend class full_curve_parameter;
// construction
public:
field( class full_curve_parameter & a );
virtual unsigned rand( unsigned base );
// methods
private:
typedef unsigned poly[ 2 * MAXK ];
static void add( const poly a, const poly b, poly c );
static void copy ( const poly a, poly b );
static int equal( const poly a, const poly b );
void div( poly a, unsigned b );
void set_random( poly a );
int set_K( unsigned K, unsigned T );
void reduce( poly a );
void mul( const poly a, const poly b, poly c );
void square( const poly a, poly b );
void inverse( const poly a, poly b );
int trace( const poly a );
int slow_trace( const poly a );
void quad_solve( const poly a, poly b );
void sqrt( const poly a, poly b );
void addmul( poly a, unsigned alpha, unsigned j, const poly b );
friend field_element sqrt( const field_element x );
void unpack( const bigint & x, poly a );
bigint pack( const poly a );
// properties
private:
const unsigned M, K, T;
unsigned prng;
poly nzt; // element with non-zero trace
poly tm; // trace mask ( trace(x) is number of bits in x & tm )
};
class field_element
{
friend class field;
friend class curve;
friend class point;
friend field_element sqrt( const field_element x );
// construction
public:
field_element( const field_element & x );
field_element( field * F );
field_element();
// methods
public:
int operator == ( const field_element & x ) const;
int operator == ( unsigned x ) const;
field_element operator + ( const field_element & x ) const;
field_element operator * ( const field_element & x ) const;
field_element operator / ( const field_element & x ) const;
field_element & operator = ( const field_element & x );
// properties
private:
field * f;
field::poly v;
};
class point
{
friend class curve;
friend class ec_crypt;
friend point operator * ( const bigint & k, const point & P );
// construction
public:
point();
point( const point & P );
point( curve * C );
// methods
public:
point & operator = ( const point & P );
point operator + ( const point & P ) const;
point operator - ( const point & P ) const;
// properties
private:
curve * c;
field_element x, y;
};
struct curve_parameter
{
unsigned L;
unsigned K;
unsigned T;
unsigned root;
unsigned b;
unsigned nso;
unsigned ntf;
};
class full_curve_parameter : public curve_parameter
{
// construction
public:
full_curve_parameter( const curve_parameter & bp );
// properties
public:
bigint tm, p0, P0;
};
class curve : public field
{
friend class curve_factory;
friend class point;
friend point operator * ( const bigint & k, const point & P );
// construction
public:
curve( full_curve_parameter & a );
// methods
public:
point random_point();
static bigint pack( const point & P );
point unpack( const bigint & X );
static bigint to_vlong( const point & P );
// methods
private:
void add( const point & P, const point & Q, point & R );
void sub( const point & P, const point & Q, point & R );
void mul( const point & P, const bigint & x, point & Q );
int calc_y( point & R, unsigned ybit=0 );
static int MOV( unsigned B, const bigint & q, const bigint & r );
static bigint small_lucas( bigint P, bigint Z, unsigned ik );
static unsigned ybit( const field_element & x );
static field_element sq( const field_element & x );
// properties
public:
point PP; // point with prime order
bigint p; // prime order of P
// properties
private:
field_element b;
};
class curve_factory // Used for calculating curve_parameter but in practice
// use pre-calculated table ncdata.hpp or equivalent
{
// construction
public:
curve_factory( unsigned L ); // can take a long time
~curve_factory();
// methods
public:
int find( unsigned K, curve_parameter & result );
// properties
private:
unsigned L;
unsigned root;
unsigned so_min;
unsigned so_max;
unsigned *so_set;
bigint comp;
};
struct bigint_pair
{
bigint r;
bigint s;
};
class ECC_BASE : private curve
{
// construction
public:
ECC_BASE( full_curve_parameter & a );
~ECC_BASE();
// methods
public:
virtual unsigned rand( unsigned base );
bigint create_private_key();
bigint create_public_key( const bigint & private_key );
bigint encrypt( const bigint & public_key, bigint & message );
bigint decrypt( const bigint & private_key, const bigint & message );
bigint_pair schnorr_sign( const bigint & msg, const bigint & private_key, bigint (*hash)(const bigint &, const bigint &) = 0, unsigned hashbits = 1 );
bool schnorr_verify( const bigint & msg, const bigint_pair & sig, const bigint & public_key, bigint (*hash)(const bigint &, const bigint &) = 0, unsigned hashbits = 1 );
bigint_pair dsa_sign( const bigint & msg, const bigint & private_key, bigint (*hash)(const bigint &, const bigint &));
bool dsa_verify( const bigint & msg, const bigint_pair & sig, const bigint & public_key, bigint (*hash)(const bigint &, const bigint &));
// properties
public:
const unsigned bits; // number of bits in prime order
#ifdef WIN32
HCRYPTPROV m_cryptProv;
#endif
};