blob: fb0b87ab8b688f292893cd01382c26b27ab5f0bf [file] [log] [blame]
nagendra modadugu4fae5422016-05-10 16:11:54 -07001// Copyright 2016 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14#include <errno.h>
15#include <stdlib.h>
16#include <stdio.h>
nagendra modadugu793cf592019-10-09 14:07:05 -070017#include <string.h>
nagendra modadugu4fae5422016-05-10 16:11:54 -070018
19#include "cryptoc/p256.h"
20
21#define _TOSTR(x) #x
22#define TOSTR(x) _TOSTR(x)
23#define CHECK(x) \
24 do { if (!(x)) { \
25 errno = EADV; \
26 perror(#x " @ line " TOSTR(__LINE__)); exit(1); }} while(0)
27
28static int count_bits(const p256_int* a) {
29 int i, n = 0;
30 for (i = 0; i < 256; ++i) {
31 n += p256_get_bit(a, i);
32 }
33 return n;
34}
35
36// Confirm the CPU's right shift is an arithmetic shift
37void test_cpu_behavior() {
38 int32_t i;
39 volatile int32_t val = -1;
40 uint32_t one = 1;
41
42 for (i = 0; i < 32; i++) {
43 CHECK((val>>i) == (-1));
44 }
45
46 for (i = 0; i < 32; i++) {
47 CHECK(0 != (((uint32_t)(val>>i)) & (one<<i)));
48 }
49}
50
51void test_shifts() {
52 p256_int a = {{1}};
53 p256_int b;
54 int i;
55
56 // First shift bit up one step at a time.
57 for (i = 0; i < 255; ++i) {
58 CHECK(p256_get_bit(&a, i) == 1);
59 CHECK(!p256_is_zero(&a));
60 CHECK(p256_shl(&a, 1, &a) == 0);
61 CHECK(p256_get_bit(&a, i) == 0);
62 CHECK(count_bits(&a) == 1);
63 }
64 CHECK(p256_get_bit(&a, i) == 1);
65 CHECK(!p256_is_zero(&a));
66
67 // Shift bit out top.
68 CHECK(p256_shl(&a, 1, &b) == 1);
69 CHECK(p256_get_bit(&b, i) == 0);
70 CHECK(p256_is_zero(&b));
71
72 // Shift bit back down.
73 for (; i > 0; --i) {
74 CHECK(p256_get_bit(&a, i) == 1);
75 CHECK(!p256_is_zero(&a));
76 p256_shr(&a, 1, &a);
77 CHECK(p256_get_bit(&a, i) == 0);
78 CHECK(count_bits(&a) == 1);
79 }
80
81 CHECK(p256_get_bit(&a, i) == 1);
82 CHECK(!p256_is_zero(&a));
83
84 // Shift bit out bottom.
85 p256_shr(&a, 1, &a);
86 CHECK(p256_is_zero(&a));
87}
88
89void test_add_sub_cmp() {
90 p256_int a = {{1}};
91 p256_int b;
92 p256_int one = {{1}};
93 int i;
94
95 for (i = 0; i < 255; ++i) {
96 CHECK(count_bits(&a) == 1);
97 CHECK(p256_sub(&a, &one, &b) == 0);
98 CHECK(p256_cmp(&a, &b) == 1);
99 CHECK(p256_cmp(&b, &a) == -1);
100 CHECK(count_bits(&b) == i);
101 CHECK(p256_add(&b, &one, &b) == 0);
102 CHECK(count_bits(&b) == 1);
103 CHECK(p256_cmp(&b, &a) == 0);
104
105 CHECK(p256_shl(&a, 1, &a) == 0);
106 }
107
108 CHECK(p256_add(&a, &a, &b) == 1); // expect carry
109 CHECK(p256_is_zero(&b));
110 CHECK(p256_cmp(&b, &a) == -1);
111 CHECK(p256_sub(&b, &one, &b) == -1); // expect borrow
112 CHECK(p256_cmp(&b, &a) == 1);
113}
114
115void test_mul_inv() {
116 p256_int a = {{1}};
117 p256_int one = {{1}};
118 p256_int b, c;
119 int i;
120
121 for (i = 0; i < 255; ++i) {
122 p256_modinv(&SECP256r1_n, &a, &b); // b = 1/a
123 p256_modmul(&SECP256r1_n, &a, 0, &b, &c); // c = b * a = 1/a * a = 1
124 CHECK(p256_cmp(&c, &one) == 0);
125
126 p256_modinv_vartime(&SECP256r1_n, &b, &c); // c = 1/b = 1/1/a = a
127 CHECK(p256_cmp(&a, &c) == 0);
128
129 CHECK(p256_shl(&a, 1, &a) == 0);
130 }
131}
132
133void test_valid_point() {
134 // Constructed x where p < x^3-3x+b < 2^256, unreduced.
135 // Computed matching y to make valid point.
136 p256_int x = {{0x3de86868, 0x1c4c6c08, 0x22d79c, 0, 0, 0, 0, 0}};
137 p256_int y = {{0xf7cc27ae, 0x29181e9d, 0xcb78ccd6, 0x43800616,
138 0x86508edc, 0x13f5f534, 0x138ffcd1, 0x6b1c4fae}};
139
140 CHECK(p256_is_valid_point(&x, &y) == 1);
141}
142
nagendra modadugu793cf592019-10-09 14:07:05 -0700143void test_bin() {
144 p256_int a = {{1}};
145 p256_int b;
146 uint8_t a_bytes_be[P256_NBYTES];
147 uint8_t a_bytes_le[P256_NBYTES];
148 int i;
149
150 p256_to_bin(&a, a_bytes_be);
151 p256_to_le_bin(&a, a_bytes_le);
152
153 // Check big-endian serialization.
154 for (i = 0; i < P256_NBYTES - 1; ++i) {
155 CHECK(a_bytes_be[i] == 0);
156 }
157 CHECK(a_bytes_be[P256_NBYTES - 1] == 1);
158
159 // Check little-endian serialization.
160 CHECK(a_bytes_le[0] == 1);
161 for (i = 1; i < P256_NBYTES; ++i) {
162 CHECK(a_bytes_le[i] == 0);
163 }
164
165 // Check big-endian parsing.
166 p256_from_bin(a_bytes_be, &b);
167 CHECK(memcmp(&a, &b, sizeof(a)) == 0);
168
169 // Check little-endian parsing.
170 p256_from_le_bin(a_bytes_le, &b);
171 CHECK(memcmp(&a, &b, sizeof(a)) == 0);
172}
173
nagendra modadugu4fae5422016-05-10 16:11:54 -0700174int main(int argc, char* argv[]) {
175 test_cpu_behavior();
176 test_shifts();
177 test_add_sub_cmp();
178 test_mul_inv();
179 test_valid_point();
nagendra modadugu793cf592019-10-09 14:07:05 -0700180 test_bin();
nagendra modadugu4fae5422016-05-10 16:11:54 -0700181 return 0;
182}