blob: 465a1b9225cf11de3bb0228b6c383a0442d13ea9 [file] [log] [blame]
Ethan Yonker1e4a1992014-11-06 09:05:01 -06001/*
2 * Copyright 2013 The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of Google Inc. nor the names of its contributors may
12 * be used to endorse or promote products derived from this software
13 * without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_
28#define SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_
29
30// Collection of routines manipulating 256 bit unsigned integers.
31// Just enough to implement ecdsa-p256 and related algorithms.
32
33#include <stdint.h>
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39#define P256_BITSPERDIGIT 32
40#define P256_NDIGITS 8
41#define P256_NBYTES 32
42
43typedef int p256_err;
44typedef uint32_t p256_digit;
45typedef int32_t p256_sdigit;
46typedef uint64_t p256_ddigit;
47typedef int64_t p256_sddigit;
48
49// Defining p256_int as struct to leverage struct assigment.
50typedef struct {
51 p256_digit a[P256_NDIGITS];
52} p256_int;
53
54extern const p256_int SECP256r1_n; // Curve order
55extern const p256_int SECP256r1_p; // Curve prime
56extern const p256_int SECP256r1_b; // Curve param
57
58// Initialize a p256_int to zero.
59void p256_init(p256_int* a);
60
61// Clear a p256_int to zero.
62void p256_clear(p256_int* a);
63
64// Return bit. Index 0 is least significant.
65int p256_get_bit(const p256_int* a, int index);
66
67// b := a % MOD
68void p256_mod(
69 const p256_int* MOD,
70 const p256_int* a,
71 p256_int* b);
72
73// c := a * (top_b | b) % MOD
74void p256_modmul(
75 const p256_int* MOD,
76 const p256_int* a,
77 const p256_digit top_b,
78 const p256_int* b,
79 p256_int* c);
80
81// b := 1 / a % MOD
82// MOD best be SECP256r1_n
83void p256_modinv(
84 const p256_int* MOD,
85 const p256_int* a,
86 p256_int* b);
87
88// b := 1 / a % MOD
89// MOD best be SECP256r1_n
90// Faster than p256_modinv()
91void p256_modinv_vartime(
92 const p256_int* MOD,
93 const p256_int* a,
94 p256_int* b);
95
96// b := a << (n % P256_BITSPERDIGIT)
97// Returns the bits shifted out of most significant digit.
98p256_digit p256_shl(const p256_int* a, int n, p256_int* b);
99
100// b := a >> (n % P256_BITSPERDIGIT)
101void p256_shr(const p256_int* a, int n, p256_int* b);
102
103int p256_is_zero(const p256_int* a);
104int p256_is_odd(const p256_int* a);
105int p256_is_even(const p256_int* a);
106
107// Returns -1, 0 or 1.
108int p256_cmp(const p256_int* a, const p256_int *b);
109
110// c: = a - b
111// Returns -1 on borrow.
112int p256_sub(const p256_int* a, const p256_int* b, p256_int* c);
113
114// c := a + b
115// Returns 1 on carry.
116int p256_add(const p256_int* a, const p256_int* b, p256_int* c);
117
118// c := a + (single digit)b
119// Returns carry 1 on carry.
120int p256_add_d(const p256_int* a, p256_digit b, p256_int* c);
121
122// ec routines.
123
124// {out_x,out_y} := nG
125void p256_base_point_mul(const p256_int *n,
126 p256_int *out_x,
127 p256_int *out_y);
128
129// {out_x,out_y} := n{in_x,in_y}
130void p256_point_mul(const p256_int *n,
131 const p256_int *in_x,
132 const p256_int *in_y,
133 p256_int *out_x,
134 p256_int *out_y);
135
136// {out_x,out_y} := n1G + n2{in_x,in_y}
137void p256_points_mul_vartime(
138 const p256_int *n1, const p256_int *n2,
139 const p256_int *in_x, const p256_int *in_y,
140 p256_int *out_x, p256_int *out_y);
141
142// Return whether point {x,y} is on curve.
143int p256_is_valid_point(const p256_int* x, const p256_int* y);
144
145// Outputs big-endian binary form. No leading zero skips.
146void p256_to_bin(const p256_int* src, uint8_t dst[P256_NBYTES]);
147
148// Reads from big-endian binary form,
149// thus pre-pad with leading zeros if short.
150void p256_from_bin(const uint8_t src[P256_NBYTES], p256_int* dst);
151
152#define P256_DIGITS(x) ((x)->a)
153#define P256_DIGIT(x,y) ((x)->a[y])
154
155#define P256_ZERO {{0}}
156#define P256_ONE {{1}}
157
158#ifdef __cplusplus
159}
160#endif
161
162#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_