|
| cECPGroup () noexcept |
|
| ~cECPGroup () |
|
void | SetEmptyECPGroup () |
|
ECPGroup_TYPE | get_ECPGroupId () const noexcept |
|
const cECPGroupDef * | get_ECPGroupDef () const noexcept |
|
HRESULT | put_ECPGroupDef (const cECPGroupDef *pECPGroupDef) |
|
HRESULT | put_ECPGroupId (ECPGroup_TYPE eECPGroupId) |
|
HRESULT | SetECParameters (const cASNBuf ¶ms) |
|
HRESULT | DoMult (OUT cECPPoint &R, const cBigUnsigned &m, const cECPPoint &P, IRandomNoise *pRandom) const |
|
HRESULT | SetCopyECP (const cECPGroup &rSrc) |
|
HRESULT | GenerateKeys (cBigUnsigned &d, cECPPoint &Q, IRandomNoise *pRandom) const |
|
HRESULT | IsValidPublicKey (const cECPPoint &pt) const |
|
HRESULT | MakeSignatureECDSA (OUT cBigInteger &r, OUT cBigInteger &s, const cBigInteger &d, const BYTE *buf, size_t nSizeBuffer, IRandomNoise *pRandom) const |
|
HRESULT | VerifySignatureECDSA (const BYTE *buf, size_t nSizeBuffer, const cECPPoint &Q, const cBigInteger &r, const cBigInteger &s) const |
|
| UNITTEST_FRIEND (cECPGroup) |
|
| cECPGroupParams () |
|
ECP_CurveType_t | get_ECP_CurveType () const |
|
size_t | get_SizeP () const |
|
void | DoModPLo (OUT cBigInteger &N) const |
|
void | DoModPHi (OUT cBigInteger &N) const |
|
bool | IsMatchECPParams (const cECPGroupParams &ref) const |
|
HRESULT | IsValidPrivateKey (const cBigUnsigned &d) const |
|
void | UpdateBits () |
|
void | InjectCommon () |
|
HRESULT | SetCopyECP (const THIS_t &rSrc) |
|
void | SetEmptyECPGroup () |
|
HRESULT | ReadSpecifiedECDomain (cASNReader &r) |
|
HRESULT | SetECPGroupFromStr (RADIX_t radix, const char *p, const char *b, const char *gx, const char *gy, const char *n) |
|
HRESULT | ReadBigIntECDSA (OUT cBigInteger &x, const BYTE *buf, size_t nSizeBuffer) const |
|
|
HRESULT | DoModP (OUT cBigInteger &N) const |
|
HRESULT | DoMulModP (OUT cBigInteger &X, const cBigInteger &Y, const cBigInteger &Z) const |
|
HRESULT | DoAddMixed (OUT cECPPoint &R, const cECPPoint &P, const cECPPoint &Q) const |
|
HRESULT | Mxz_normalize (cECPPoint &P) const |
|
HRESULT | Mxz_randomize (cECPPoint &P, IRandomNoise *pRandom) const |
|
HRESULT | Mxz_add_double (cECPPoint &R, cECPPoint &S, const cECPPoint &P, const cECPPoint &Q, const cBigInteger &d) const |
|
HRESULT | Mxz_mul (cECPPoint &R, const cBigInteger &m, const cECPPoint &P, IRandomNoise *pRandom) const |
|
HRESULT | Jac_normalize (cECPPoint &pt) const |
|
HRESULT | Jac_normalize_many (cECPPoint *pT[], ITERATE_t t_len) const |
|
HRESULT | Jac_double (cECPPoint &R, const cECPPoint &P) const |
|
HRESULT | Jac_randomize (cECPPoint &pt, IRandomNoise *pRandom) const |
|
HRESULT | Jac_safe_invert (cECPPoint &Q, bool inv) const |
|
HRESULT | Comb_precompute (cECPPoint T[], const cECPPoint &P, BYTE w, size_t d) const |
|
HRESULT | Comb_mul_core (cECPPoint &R, const cECPPoint T[], BYTE t_len, const BYTE x[], size_t d, IRandomNoise *pRandom) const |
|
HRESULT | Comb_mul (OUT cECPPoint &R, const cBigUnsigned &m, const cECPPoint &P, IRandomNoise *pRandom) const |
|
HRESULT | Comb_select (cECPPoint &R, const cECPPoint T[], BYTE t_len, BYTE i) const |
|
HRESULT | DoAdd (OUT cECPPoint &R, const cECPPoint &P, const cECPPoint &Q) const |
|
HRESULT | DoSub (cECPPoint &R, const cECPPoint &P, const cECPPoint &Q) const |
|
HRESULT | IsValidPublicKeyWS (const cECPPoint &pt) const |
|
HRESULT | IsValidPublicKeyMX (const cECPPoint &pt) const |
|
ECP group structure
We consider two types of curves equations: ECP_CurveType_t
- Short Weierstrass y^2 = x^3 + A x + B mod P (SEC1 + RFC 4492)
- Montgomery, y^2 = x^3 + A x^2 + x mod P (M255 + draft) ecdh_x25519
In both cases, a generator G for a prime-order subgroup is fixed. In the short Weierstrass, this subgroup is actually the whole curve, and its cardinal is denoted by N.
In the case of ECP_CurveType_SHORT_WEIERSTRASS, our code requires that N is an odd prime. (Use odd in DoMult() and prime in MakeSignatureECDSA() for blinding.)
In the case of ECP_CurveType_MONTGOMERY, we don't store A but (A + 2) / 4 which is the quantity actually used in the formulas. Also, nbits is not the size of N but the required size for private keys.
Precompute points for the comb method
If i = i_{w-1} ... i_1 is the binary representation of i, then T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P
T must be able to hold 2^{w - 1} elements
Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1)
Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22)
The coordinates of Q must be normalized (= affine), but those of P don't need to. R is not normalized.
Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. None of these cases can happen as intermediate step in Comb_mul():
- at each step, P, Q and R are multiples of the base point, the factor being less than its order, so none of them is zero;
- Q is an odd multiple of the base point, P an even multiple, due to the choice of precomputed points in the modified comb method. So branches for these cases do not leak secret information.
We accept Q.Z being unset (saving memory in tables) as meaning 1.
Cost: 1A := 8M + 3S
ECP_CurveType_SHORT_WEIERSTRASS Point doubling R = 2 P, Jacobian coordinates
Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-Jacobian.html#doubling-dbl-1998-cmo-2 .
We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring.
Standard optimizations are applied when curve parameter A is one of { 0, -3 }.
Cost: 1D := 3M + 4S (A == 0) 4M + 4S (A == -3) 3M + 6S + 1a otherwise
ECP_CurveType_SHORT_WEIERSTRASS Normalize Jacobian coordinates of an array of (pointers to) points, using Montgomery's trick to perform only one inversion mod P. (See for example Cohen's "A Course in Computational Algebraic Number
Theory", Algorithm 10.3.4.)
Warning: fails (returning an error) if one of the points is zero! This should never happen, see choice of w in Comb_mul().
Cost: 1N(t) := 1I + (6t - 3)M + 1S