Internet Research Task Force (IRTF) A. Langley
Request for Comments: 7748 Google
Category: Informational M. Hamburg
ISSN: 2070-1721 Rambus Cryptography Research
S. Turner
sn3rd
January 2016
Elliptic Curves for Security
Abstract
This memo specifies two elliptic curves over prime fields that offer
a high level of practical security in cryptographic applications,
including Transport Layer Security (TLS). These curves are intended
to operate at the ~128-bit and ~224-bit security level, respectively,
and are generated deterministically based on a list of required
properties.
Status of This Memo
This document is not an Internet Standards Track specification; it is
published for informational purposes.
This document is a product of the Internet Research Task Force
(IRTF). The IRTF publishes the results of Internet-related research
and development activities. These results might not be suitable for
deployment. This RFC represents the consensus of the Crypto Forum
Research Group of the Internet Research Task Force (IRTF). Documents
approved for publication by the IRSG are not a candidate for any
level of Internet Standard; see Section 2 of RFC 5741.
Information about the current status of this document, any errata,
and how to provide feedback on it may be obtained at
http://www.rfc-editor.org/info/rfc7748.
Copyright Notice
Copyright (c) 2016 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document.
Langley, et al. Informational [Page 1]Elliptic Curves for Security
Abstract
This memo specifies two elliptic curves over prime fields that offer a high level of practical security in cryptographic applications, including Transport Layer Security (TLS). These curves are intended to operate at the ~128-bit and ~224-bit security level, respectively, and are generated deterministically based on a list of required properties.
Status of This Memo
This document is not an Internet Standards Track specification; it is published for informational purposes.
This document is a product of the Internet Research Task Force (IRTF). The IRTF publishes the results of Internet-related research and development activities. These results might not be suitable for deployment. This RFC represents the consensus of the Crypto Forum Research Group of the Internet Research Task Force (IRTF). Documents approved for publication by the IRSG are not a candidate for any level of Internet Standard; see Section 2 of RFC 5741.
Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc7748.
Copyright Notice
Copyright (c) 2016 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document.
//! X25519 after RFC 7748, section 5: the Montgomery ladder on Curve25519.//! Every step does the same work whatever the key, so timing leaks nothing.use crate::field::Fe; // integers mod 2^255 - 19/// (A - 2) / 4 for Curve25519, where A = 486662.const A24: u32 = 121_665; ■ (486662 − 2) / 4/// Clear the low three bits and bit 255, and set bit 254.fn clamp(mut k: [u8; 32]) -> [u8; 32] {│ k[0] &= 248;│ k[31] &= 127;│ k[31] |= 64;│ k}/// Multiply the point with u-coordinate u by the scalar k.pub fn x25519(k: [u8; 32], u: [u8; 32]) -> [u8; 32] {│ let k = clamp(k);│ let x1 = Fe::from_bytes(&u); // the top bit of u is ignored│ let (mut x2, mut z2) = (Fe::ONE, Fe::ZERO);│ let (mut x3, mut z3) = (x1, Fe::ONE);│ let mut swap = 0;│ for t in (0..255).rev() {│ │ let k_t = (k[t >> 3] >> (t & 7)) & 1;│ │ swap ^= k_t;│ │ Fe::cswap(swap, &mut x2, &mut x3);│ │ Fe::cswap(swap, &mut z2, &mut z3);│ │ swap = k_t;│ │ let a = x2 + z2;│ │ let aa = a.square();│ │ let b = x2 - z2;│ │ let bb = b.square();│ │ let e = aa - bb;│ │ let c = x3 + z3;│ │ let d = x3 - z3;│ │ let da = d * a;│ │ let cb = c * b;│ │ x3 = (da + cb).square();│ │ z3 = x1 * (da - cb).square();│ │ x2 = aa * bb;│ │ z2 = e * (aa + e.mul_small(A24));│ }│ Fe::cswap(swap, &mut x2, &mut x3);│ Fe::cswap(swap, &mut z2, &mut z3);│ (x2 * z2.invert()).to_bytes()}#[cfg(test)]mod tests {│ use super::*;│ use hex_literal::hex;│ #[test]│ fn rfc7748_section_5_2() {│ │ let k = hex!("a546e36bf0527c9d3b16154b82465edd"│ │ │ "62144c0ac1fc5a18506a2244ba449ac4");│ │ let u = hex!("e6db6867583030db3594c1a424b15f7c"│ │ │ "726624ec26b3353b10a903a6d0ab1c4c");│ │ let r = hex!("c3da55379de9c6908e94ea4df28d084f"│ │ │ "32eccf03491c71f754b4075577a28552");│ │ assert_eq!(x25519(k, u), r);│ }}