OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This is an implementation of the P224 elliptic curve group. It's written to | 5 // This is an implementation of the P224 elliptic curve group. It's written to |
6 // be short and simple rather than fast, although it's still constant-time. | 6 // be short and simple rather than fast, although it's still constant-time. |
7 // | 7 // |
8 // See http://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background. | 8 // See http://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background. |
9 | 9 |
10 #include "crypto/p224.h" | 10 #include "crypto/p224.h" |
11 | 11 |
12 #include <string.h> | 12 #include <string.h> |
13 | 13 |
14 #include "base/sys_byteorder.h" | 14 #include "base/sys_byteorder.h" |
15 | 15 |
16 #if defined(OS_WIN) | 16 namespace { |
17 // Allow htonl/ntohl to be called without requiring ws2_32.dll to be loaded, | |
18 // which isn't available in Chrome's sandbox. See crbug.com/116591. | |
19 // TODO(wez): Replace these calls with base::htonl() etc when available. | |
20 #define ntohl(x) _byteswap_ulong(x) | |
21 #define htonl(x) _byteswap_ulong(x) | |
22 #endif // OS_WIN | |
23 | 17 |
24 namespace { | 18 using base::HostToNet32; |
| 19 using base::NetToHost32; |
25 | 20 |
26 // Field element functions. | 21 // Field element functions. |
27 // | 22 // |
28 // The field that we're dealing with is ℤ/pℤ where p = 2**224 - 2**96 + 1. | 23 // The field that we're dealing with is ℤ/pℤ where p = 2**224 - 2**96 + 1. |
29 // | 24 // |
30 // Field elements are represented by a FieldElement, which is a typedef to an | 25 // Field elements are represented by a FieldElement, which is a typedef to an |
31 // array of 8 uint32's. The value of a FieldElement, a, is: | 26 // array of 8 uint32's. The value of a FieldElement, a, is: |
32 // a[0] + 2**28·a[1] + 2**56·a[1] + ... + 2**196·a[7] | 27 // a[0] + 2**28·a[1] + 2**56·a[1] + ... + 2**196·a[7] |
33 // | 28 // |
34 // Using 28-bit limbs means that there's only 4 bits of headroom, which is less | 29 // Using 28-bit limbs means that there's only 4 bits of headroom, which is less |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 CopyConditional(out, a, first_bit & bit); | 552 CopyConditional(out, a, first_bit & bit); |
558 CopyConditional(out, tmp, ~first_bit & bit); | 553 CopyConditional(out, tmp, ~first_bit & bit); |
559 first_bit = first_bit & ~bit; | 554 first_bit = first_bit & ~bit; |
560 } | 555 } |
561 } | 556 } |
562 } | 557 } |
563 | 558 |
564 // Get224Bits reads 7 words from in and scatters their contents in | 559 // Get224Bits reads 7 words from in and scatters their contents in |
565 // little-endian form into 8 words at out, 28 bits per output word. | 560 // little-endian form into 8 words at out, 28 bits per output word. |
566 void Get224Bits(uint32* out, const uint32* in) { | 561 void Get224Bits(uint32* out, const uint32* in) { |
567 out[0] = ntohl(in[6]) & kBottom28Bits; | 562 out[0] = NetToHost32(in[6]) & kBottom28Bits; |
568 out[1] = ((ntohl(in[5]) << 4) | (ntohl(in[6]) >> 28)) & kBottom28Bits; | 563 out[1] = ((NetToHost32(in[5]) << 4) | |
569 out[2] = ((ntohl(in[4]) << 8) | (ntohl(in[5]) >> 24)) & kBottom28Bits; | 564 (NetToHost32(in[6]) >> 28)) & kBottom28Bits; |
570 out[3] = ((ntohl(in[3]) << 12) | (ntohl(in[4]) >> 20)) & kBottom28Bits; | 565 out[2] = ((NetToHost32(in[4]) << 8) | |
571 out[4] = ((ntohl(in[2]) << 16) | (ntohl(in[3]) >> 16)) & kBottom28Bits; | 566 (NetToHost32(in[5]) >> 24)) & kBottom28Bits; |
572 out[5] = ((ntohl(in[1]) << 20) | (ntohl(in[2]) >> 12)) & kBottom28Bits; | 567 out[3] = ((NetToHost32(in[3]) << 12) | |
573 out[6] = ((ntohl(in[0]) << 24) | (ntohl(in[1]) >> 8)) & kBottom28Bits; | 568 (NetToHost32(in[4]) >> 20)) & kBottom28Bits; |
574 out[7] = (ntohl(in[0]) >> 4) & kBottom28Bits; | 569 out[4] = ((NetToHost32(in[2]) << 16) | |
| 570 (NetToHost32(in[3]) >> 16)) & kBottom28Bits; |
| 571 out[5] = ((NetToHost32(in[1]) << 20) | |
| 572 (NetToHost32(in[2]) >> 12)) & kBottom28Bits; |
| 573 out[6] = ((NetToHost32(in[0]) << 24) | |
| 574 (NetToHost32(in[1]) >> 8)) & kBottom28Bits; |
| 575 out[7] = (NetToHost32(in[0]) >> 4) & kBottom28Bits; |
575 } | 576 } |
576 | 577 |
577 // Put224Bits performs the inverse operation to Get224Bits: taking 28 bits from | 578 // Put224Bits performs the inverse operation to Get224Bits: taking 28 bits from |
578 // each of 8 input words and writing them in big-endian order to 7 words at | 579 // each of 8 input words and writing them in big-endian order to 7 words at |
579 // out. | 580 // out. |
580 void Put224Bits(uint32* out, const uint32* in) { | 581 void Put224Bits(uint32* out, const uint32* in) { |
581 out[6] = htonl((in[0] >> 0) | (in[1] << 28)); | 582 out[6] = HostToNet32((in[0] >> 0) | (in[1] << 28)); |
582 out[5] = htonl((in[1] >> 4) | (in[2] << 24)); | 583 out[5] = HostToNet32((in[1] >> 4) | (in[2] << 24)); |
583 out[4] = htonl((in[2] >> 8) | (in[3] << 20)); | 584 out[4] = HostToNet32((in[2] >> 8) | (in[3] << 20)); |
584 out[3] = htonl((in[3] >> 12) | (in[4] << 16)); | 585 out[3] = HostToNet32((in[3] >> 12) | (in[4] << 16)); |
585 out[2] = htonl((in[4] >> 16) | (in[5] << 12)); | 586 out[2] = HostToNet32((in[4] >> 16) | (in[5] << 12)); |
586 out[1] = htonl((in[5] >> 20) | (in[6] << 8)); | 587 out[1] = HostToNet32((in[5] >> 20) | (in[6] << 8)); |
587 out[0] = htonl((in[6] >> 24) | (in[7] << 4)); | 588 out[0] = HostToNet32((in[6] >> 24) | (in[7] << 4)); |
588 } | 589 } |
589 | 590 |
590 } // anonymous namespace | 591 } // anonymous namespace |
591 | 592 |
592 namespace crypto { | 593 namespace crypto { |
593 | 594 |
594 namespace p224 { | 595 namespace p224 { |
595 | 596 |
596 bool Point::SetFromString(const base::StringPiece& in) { | 597 bool Point::SetFromString(const base::StringPiece& in) { |
597 if (in.size() != 2*28) | 598 if (in.size() != 2*28) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 Subtract(&out->y, kP, y); | 678 Subtract(&out->y, kP, y); |
678 Reduce(&out->y); | 679 Reduce(&out->y); |
679 | 680 |
680 memset(&out->z, 0, sizeof(out->z)); | 681 memset(&out->z, 0, sizeof(out->z)); |
681 out->z[0] = 1; | 682 out->z[0] = 1; |
682 } | 683 } |
683 | 684 |
684 } // namespace p224 | 685 } // namespace p224 |
685 | 686 |
686 } // namespace crypto | 687 } // namespace crypto |
OLD | NEW |