blob: 03954eb97e2c2292f2196da62d5d0fcc4961ced8 [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>
17
18#include "cryptoc/p256.h"
19
20#define _TOSTR(x) #x
21#define TOSTR(x) _TOSTR(x)
22#define CHECK(x) \
23 do { if (!(x)) { \
24 errno = EADV; \
25 perror(#x " @ line " TOSTR(__LINE__)); exit(1); }} while(0)
26
27static int count_bits(const p256_int* a) {
28 int i, n = 0;
29 for (i = 0; i < 256; ++i) {
30 n += p256_get_bit(a, i);
31 }
32 return n;
33}
34
35// Confirm the CPU's right shift is an arithmetic shift
36void test_cpu_behavior() {
37 int32_t i;
38 volatile int32_t val = -1;
39 uint32_t one = 1;
40
41 for (i = 0; i < 32; i++) {
42 CHECK((val>>i) == (-1));
43 }
44
45 for (i = 0; i < 32; i++) {
46 CHECK(0 != (((uint32_t)(val>>i)) & (one<<i)));
47 }
48}
49
50void test_shifts() {
51 p256_int a = {{1}};
52 p256_int b;
53 int i;
54
55 // First shift bit up one step at a time.
56 for (i = 0; i < 255; ++i) {
57 CHECK(p256_get_bit(&a, i) == 1);
58 CHECK(!p256_is_zero(&a));
59 CHECK(p256_shl(&a, 1, &a) == 0);
60 CHECK(p256_get_bit(&a, i) == 0);
61 CHECK(count_bits(&a) == 1);
62 }
63 CHECK(p256_get_bit(&a, i) == 1);
64 CHECK(!p256_is_zero(&a));
65
66 // Shift bit out top.
67 CHECK(p256_shl(&a, 1, &b) == 1);
68 CHECK(p256_get_bit(&b, i) == 0);
69 CHECK(p256_is_zero(&b));
70
71 // Shift bit back down.
72 for (; i > 0; --i) {
73 CHECK(p256_get_bit(&a, i) == 1);
74 CHECK(!p256_is_zero(&a));
75 p256_shr(&a, 1, &a);
76 CHECK(p256_get_bit(&a, i) == 0);
77 CHECK(count_bits(&a) == 1);
78 }
79
80 CHECK(p256_get_bit(&a, i) == 1);
81 CHECK(!p256_is_zero(&a));
82
83 // Shift bit out bottom.
84 p256_shr(&a, 1, &a);
85 CHECK(p256_is_zero(&a));
86}
87
88void test_add_sub_cmp() {
89 p256_int a = {{1}};
90 p256_int b;
91 p256_int one = {{1}};
92 int i;
93
94 for (i = 0; i < 255; ++i) {
95 CHECK(count_bits(&a) == 1);
96 CHECK(p256_sub(&a, &one, &b) == 0);
97 CHECK(p256_cmp(&a, &b) == 1);
98 CHECK(p256_cmp(&b, &a) == -1);
99 CHECK(count_bits(&b) == i);
100 CHECK(p256_add(&b, &one, &b) == 0);
101 CHECK(count_bits(&b) == 1);
102 CHECK(p256_cmp(&b, &a) == 0);
103
104 CHECK(p256_shl(&a, 1, &a) == 0);
105 }
106
107 CHECK(p256_add(&a, &a, &b) == 1); // expect carry
108 CHECK(p256_is_zero(&b));
109 CHECK(p256_cmp(&b, &a) == -1);
110 CHECK(p256_sub(&b, &one, &b) == -1); // expect borrow
111 CHECK(p256_cmp(&b, &a) == 1);
112}
113
114void test_mul_inv() {
115 p256_int a = {{1}};
116 p256_int one = {{1}};
117 p256_int b, c;
118 int i;
119
120 for (i = 0; i < 255; ++i) {
121 p256_modinv(&SECP256r1_n, &a, &b); // b = 1/a
122 p256_modmul(&SECP256r1_n, &a, 0, &b, &c); // c = b * a = 1/a * a = 1
123 CHECK(p256_cmp(&c, &one) == 0);
124
125 p256_modinv_vartime(&SECP256r1_n, &b, &c); // c = 1/b = 1/1/a = a
126 CHECK(p256_cmp(&a, &c) == 0);
127
128 CHECK(p256_shl(&a, 1, &a) == 0);
129 }
130}
131
132void test_valid_point() {
133 // Constructed x where p < x^3-3x+b < 2^256, unreduced.
134 // Computed matching y to make valid point.
135 p256_int x = {{0x3de86868, 0x1c4c6c08, 0x22d79c, 0, 0, 0, 0, 0}};
136 p256_int y = {{0xf7cc27ae, 0x29181e9d, 0xcb78ccd6, 0x43800616,
137 0x86508edc, 0x13f5f534, 0x138ffcd1, 0x6b1c4fae}};
138
139 CHECK(p256_is_valid_point(&x, &y) == 1);
140}
141
142int main(int argc, char* argv[]) {
143 test_cpu_behavior();
144 test_shifts();
145 test_add_sub_cmp();
146 test_mul_inv();
147 test_valid_point();
148 return 0;
149}