Arduino Cryptography Library
P521.h
1 /*
2  * Copyright (C) 2016 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #ifndef CRYPTO_P521_h
24 #define CRYPTO_P521_h
25 
26 #include "BigNumberUtil.h"
27 
28 class Hash;
29 
30 class P521
31 {
32 public:
33 
34  static bool eval(uint8_t result[132], const uint8_t f[66], const uint8_t point[132]);
35 
36  static void dh1(uint8_t k[132], uint8_t f[66]);
37  static bool dh2(const uint8_t k[132], uint8_t f[66]);
38 
39  static void sign(uint8_t signature[132], const uint8_t privateKey[66],
40  const void *message, size_t len, Hash *hash = 0);
41  static bool verify(const uint8_t signature[132],
42  const uint8_t publicKey[132],
43  const void *message, size_t len, Hash *hash = 0);
44 
45  static void generatePrivateKey(uint8_t privateKey[66]);
46  static void derivePublicKey(uint8_t publicKey[132], const uint8_t privateKey[66]);
47 
48  static bool isValidPrivateKey(const uint8_t privateKey[66]);
49  static bool isValidPublicKey(const uint8_t publicKey[132]);
50 
51  static bool isValidCurvePoint(const uint8_t point[132])
52  {
53  return isValidPublicKey(point);
54  }
55 
56 #if defined(TEST_P521_FIELD_OPS)
57 public:
58 #else
59 private:
60 #endif
61  static void evaluate(limb_t *x, limb_t *y, const uint8_t f[66]);
62 
63  static void addAffine(limb_t *x1, limb_t *y1,
64  const limb_t *x2, const limb_t *y2);
65 
66  static bool validate(const limb_t *x, const limb_t *y);
67  static bool inRange(const limb_t *x);
68 
69  static void reduce(limb_t *result, const limb_t *x);
70  static void reduceQuick(limb_t *x);
71 
72  static void mulNoReduce(limb_t *result, const limb_t *x, const limb_t *y);
73 
74  static void mul(limb_t *result, const limb_t *x, const limb_t *y);
75  static void square(limb_t *result, const limb_t *x)
76  {
77  mul(result, x, x);
78  }
79 
80  static void mulLiteral(limb_t *result, const limb_t *x, limb_t y);
81 
82  static void add(limb_t *result, const limb_t *x, const limb_t *y);
83  static void sub(limb_t *result, const limb_t *x, const limb_t *y);
84 
85  static void dblPoint(limb_t *xout, limb_t *yout, limb_t *zout,
86  const limb_t *xin, const limb_t *yin,
87  const limb_t *zin);
88  static void addPoint(limb_t *xout, limb_t *yout, limb_t *zout,
89  const limb_t *x1, const limb_t *y1,
90  const limb_t *z1, const limb_t *x2,
91  const limb_t *y2);
92 
93  static void cmove(limb_t select, limb_t *x, const limb_t *y);
94  static void cmove1(limb_t select, limb_t *x);
95 
96  static void recip(limb_t *result, const limb_t *x);
97 
98  static void reduceQ(limb_t *result, const limb_t *r);
99  static void mulQ(limb_t *result, const limb_t *x, const limb_t *y);
100  static void recipQ(limb_t *result, const limb_t *x);
101 
102  static void generateK(uint8_t k[66], const uint8_t hm[66],
103  const uint8_t x[66], Hash *hash, uint64_t count);
104  static void generateK(uint8_t k[66], const uint8_t hm[66],
105  const uint8_t x[66], uint64_t count);
106 
107  // Constructor and destructor are private - cannot instantiate this class.
108  P521() {}
109  ~P521() {}
110 };
111 
112 #endif
Abstract base class for cryptographic hash algorithms.
Definition: Hash.h:30
Elliptic curve operations with the NIST P-521 curve.
Definition: P521.h:31
static void derivePublicKey(uint8_t publicKey[132], const uint8_t privateKey[66])
Derives the public key from a private key for P-521 signing operations.
Definition: P521.cpp:497
static bool isValidCurvePoint(const uint8_t point[132])
Validates a point to ensure that it is on the curve.
Definition: P521.h:51
static bool isValidPrivateKey(const uint8_t privateKey[66])
Validates a private key value to ensure that it is between 1 and q - 1.
Definition: P521.cpp:524
static bool dh2(const uint8_t k[132], uint8_t f[66])
Performs phase 2 of an ECDH key exchange using P-521.
Definition: P521.cpp:229
static void sign(uint8_t signature[132], const uint8_t privateKey[66], const void *message, size_t len, Hash *hash=0)
Signs a message using a specific P-521 private key.
Definition: P521.cpp:276
static bool verify(const uint8_t signature[132], const uint8_t publicKey[132], const void *message, size_t len, Hash *hash=0)
Verifies a signature using a specific P-521 public key.
Definition: P521.cpp:373
static bool eval(uint8_t result[132], const uint8_t f[66], const uint8_t point[132])
Evaluates the curve function.
Definition: P521.cpp:135
static void dh1(uint8_t k[132], uint8_t f[66])
Performs phase 1 of an ECDH key exchange using P-521.
Definition: P521.cpp:208
static void generatePrivateKey(uint8_t privateKey[66])
Generates a private key for P-521 signing operations.
Definition: P521.cpp:466
static bool isValidPublicKey(const uint8_t publicKey[132])
Validates a public key to ensure that it is a valid curve point.
Definition: P521.cpp:564