1 // -*- mode: rust; -*- 2 // 3 // This file is part of curve25519-dalek. 4 // Copyright (c) 2016-2019 Isis Lovecruft, Henry de Valence 5 // See LICENSE for licensing information. 6 // 7 // Authors: 8 // - Isis Agora Lovecruft <isis@patternsinthevoid.net> 9 // - Henry de Valence <hdevalence@hdevalence.ca> 10 11 //! Various constants, such as the Ristretto and Ed25519 basepoints. 12 //! 13 //! Most of the constants are given with 14 //! `LONG_DESCRIPTIVE_UPPER_CASE_NAMES`, but they can be brought into 15 //! scope using a `let` binding: 16 //! 17 //! ``` 18 //! use curve25519_dalek::constants; 19 //! use curve25519_dalek::traits::IsIdentity; 20 //! 21 //! let B = &constants::RISTRETTO_BASEPOINT_TABLE; 22 //! let l = &constants::BASEPOINT_ORDER; 23 //! 24 //! let A = l * B; 25 //! assert!(A.is_identity()); 26 //! ``` 27 28 #![allow(non_snake_case)] 29 30 use edwards::CompressedEdwardsY; 31 use ristretto::RistrettoPoint; 32 use ristretto::CompressedRistretto; 33 use montgomery::MontgomeryPoint; 34 use scalar::Scalar; 35 36 #[cfg(feature = "u64_backend")] 37 pub use backend::serial::u64::constants::*; 38 #[cfg(feature = "u32_backend")] 39 pub use backend::serial::u32::constants::*; 40 41 /// The Ed25519 basepoint, in `CompressedEdwardsY` format. 42 /// 43 /// This is the little-endian byte encoding of \\( 4/5 \pmod p \\), 44 /// which is the \\(y\\)-coordinate of the Ed25519 basepoint. 45 /// 46 /// The sign bit is 0 since the basepoint has \\(x\\) chosen to be positive. 47 pub const ED25519_BASEPOINT_COMPRESSED: CompressedEdwardsY = 48 CompressedEdwardsY([0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 49 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 50 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 51 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66]); 52 53 /// The X25519 basepoint, in `MontgomeryPoint` format. 54 pub const X25519_BASEPOINT: MontgomeryPoint = 55 MontgomeryPoint([0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); 59 60 /// The Ristretto basepoint, in `CompressedRistretto` format. 61 pub const RISTRETTO_BASEPOINT_COMPRESSED: CompressedRistretto = 62 CompressedRistretto([0xe2, 0xf2, 0xae, 0x0a, 0x6a, 0xbc, 0x4e, 0x71, 63 0xa8, 0x84, 0xa9, 0x61, 0xc5, 0x00, 0x51, 0x5f, 64 0x58, 0xe3, 0x0b, 0x6a, 0xa5, 0x82, 0xdd, 0x8d, 65 0xb6, 0xa6, 0x59, 0x45, 0xe0, 0x8d, 0x2d, 0x76]); 66 67 /// The Ristretto basepoint, as a `RistrettoPoint`. 68 /// 69 /// This is called `_POINT` to distinguish it from `_TABLE`, which 70 /// provides fast scalar multiplication. 71 pub const RISTRETTO_BASEPOINT_POINT: RistrettoPoint = RistrettoPoint(ED25519_BASEPOINT_POINT); 72 73 /// `BASEPOINT_ORDER` is the order of the Ristretto group and of the Ed25519 basepoint, i.e., 74 /// $$ 75 /// \ell = 2^\{252\} + 27742317777372353535851937790883648493. 76 /// $$ 77 pub const BASEPOINT_ORDER: Scalar = Scalar{ 78 bytes: [ 79 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 80 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 83 ], 84 }; 85 86 use ristretto::RistrettoBasepointTable; 87 /// The Ristretto basepoint, as a `RistrettoBasepointTable` for scalar multiplication. 88 pub const RISTRETTO_BASEPOINT_TABLE: RistrettoBasepointTable 89 = RistrettoBasepointTable(ED25519_BASEPOINT_TABLE); 90 91 #[cfg(test)] 92 mod test { 93 use field::FieldElement; 94 use traits::{IsIdentity, ValidityCheck}; 95 use constants; 96 97 #[test] test_eight_torsion()98 fn test_eight_torsion() { 99 for i in 0..8 { 100 let Q = constants::EIGHT_TORSION[i].mul_by_pow_2(3); 101 assert!(Q.is_valid()); 102 assert!(Q.is_identity()); 103 } 104 } 105 106 #[test] test_four_torsion()107 fn test_four_torsion() { 108 for i in (0..8).filter(|i| i % 2 == 0) { 109 let Q = constants::EIGHT_TORSION[i].mul_by_pow_2(2); 110 assert!(Q.is_valid()); 111 assert!(Q.is_identity()); 112 } 113 } 114 115 #[test] test_two_torsion()116 fn test_two_torsion() { 117 for i in (0..8).filter(|i| i % 4 == 0) { 118 let Q = constants::EIGHT_TORSION[i].mul_by_pow_2(1); 119 assert!(Q.is_valid()); 120 assert!(Q.is_identity()); 121 } 122 } 123 124 /// Test that SQRT_M1 is the positive square root of -1 125 #[test] test_sqrt_minus_one()126 fn test_sqrt_minus_one() { 127 let minus_one = FieldElement::minus_one(); 128 let sqrt_m1_sq = &constants::SQRT_M1 * &constants::SQRT_M1; 129 assert_eq!(minus_one, sqrt_m1_sq); 130 assert_eq!(constants::SQRT_M1.is_negative().unwrap_u8(), 0); 131 } 132 133 #[test] test_sqrt_constants_sign()134 fn test_sqrt_constants_sign() { 135 let minus_one = FieldElement::minus_one(); 136 let (was_nonzero_square, invsqrt_m1) = minus_one.invsqrt(); 137 assert_eq!(was_nonzero_square.unwrap_u8(), 1u8); 138 let sign_test_sqrt = &invsqrt_m1 * &constants::SQRT_M1; 139 assert_eq!(sign_test_sqrt, minus_one); 140 } 141 142 /// Test that d = -121665/121666 143 #[test] 144 #[cfg(feature = "u32_backend")] test_d_vs_ratio()145 fn test_d_vs_ratio() { 146 use backend::serial::u32::field::FieldElement2625; 147 let a = -&FieldElement2625([121665,0,0,0,0,0,0,0,0,0]); 148 let b = FieldElement2625([121666,0,0,0,0,0,0,0,0,0]); 149 let d = &a * &b.invert(); 150 let d2 = &d + &d; 151 assert_eq!(d, constants::EDWARDS_D); 152 assert_eq!(d2, constants::EDWARDS_D2); 153 } 154 155 /// Test that d = -121665/121666 156 #[test] 157 #[cfg(feature = "u64_backend")] test_d_vs_ratio()158 fn test_d_vs_ratio() { 159 use backend::serial::u64::field::FieldElement51; 160 let a = -&FieldElement51([121665,0,0,0,0]); 161 let b = FieldElement51([121666,0,0,0,0]); 162 let d = &a * &b.invert(); 163 let d2 = &d + &d; 164 assert_eq!(d, constants::EDWARDS_D); 165 assert_eq!(d2, constants::EDWARDS_D2); 166 } 167 168 #[test] test_sqrt_ad_minus_one()169 fn test_sqrt_ad_minus_one() { 170 let a = FieldElement::minus_one(); 171 let ad_minus_one = &(&a * &constants::EDWARDS_D) + &a; 172 let should_be_ad_minus_one = constants::SQRT_AD_MINUS_ONE.square(); 173 assert_eq!(should_be_ad_minus_one, ad_minus_one); 174 } 175 176 } 177