github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/crypto/edwards25519_field.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package crypto 6 7 // This file contains field element logic that is independent of the 8 // representation. 9 10 var zero FieldElement 11 12 func load3(in []byte) int64 { 13 var r int64 14 r = int64(in[0]) 15 r |= int64(in[1]) << 8 16 r |= int64(in[2]) << 16 17 return r 18 } 19 20 func load4(in []byte) int64 { 21 var r int64 22 r = int64(in[0]) 23 r |= int64(in[1]) << 8 24 r |= int64(in[2]) << 16 25 r |= int64(in[3]) << 24 26 return r 27 } 28 29 func FeZero(fe *FieldElement) { 30 copy(fe[:], zero[:]) 31 } 32 33 func FeOne(fe *FieldElement) { 34 FeZero(fe) 35 fe[0] = 1 36 } 37 38 func FeCopy(dst, src *FieldElement) { 39 copy(dst[:], src[:]) 40 } 41 42 func FeIsNegative(f *FieldElement) byte { 43 var s Key 44 FeToBytes(&s, f) 45 return s[0] & 1 46 } 47 48 func FeIsNonZero(f *FieldElement) int32 { 49 var s Key 50 FeToBytes(&s, f) 51 var x uint8 52 for _, b := range s { 53 x |= b 54 } 55 x |= x >> 4 56 x |= x >> 2 57 x |= x >> 1 58 return int32(x & 1) 59 } 60 61 func FeInvert(out, z *FieldElement) { 62 var t0, t1, t2, t3 FieldElement 63 var i int 64 65 FeSquare(&t0, z) // 2^1 66 FeSquare(&t1, &t0) // 2^2 67 for i = 1; i < 2; i++ { // 2^3 68 FeSquare(&t1, &t1) 69 } 70 FeMul(&t1, z, &t1) // 2^3 + 2^0 71 FeMul(&t0, &t0, &t1) // 2^3 + 2^1 + 2^0 72 FeSquare(&t2, &t0) // 2^4 + 2^2 + 2^1 73 FeMul(&t1, &t1, &t2) // 2^4 + 2^3 + 2^2 + 2^1 + 2^0 74 FeSquare(&t2, &t1) // 5,4,3,2,1 75 for i = 1; i < 5; i++ { // 9,8,7,6,5 76 FeSquare(&t2, &t2) 77 } 78 FeMul(&t1, &t2, &t1) // 9,8,7,6,5,4,3,2,1,0 79 FeSquare(&t2, &t1) // 10..1 80 for i = 1; i < 10; i++ { // 19..10 81 FeSquare(&t2, &t2) 82 } 83 FeMul(&t2, &t2, &t1) // 19..0 84 FeSquare(&t3, &t2) // 20..1 85 for i = 1; i < 20; i++ { // 39..20 86 FeSquare(&t3, &t3) 87 } 88 FeMul(&t2, &t3, &t2) // 39..0 89 FeSquare(&t2, &t2) // 40..1 90 for i = 1; i < 10; i++ { // 49..10 91 FeSquare(&t2, &t2) 92 } 93 FeMul(&t1, &t2, &t1) // 49..0 94 FeSquare(&t2, &t1) // 50..1 95 for i = 1; i < 50; i++ { // 99..50 96 FeSquare(&t2, &t2) 97 } 98 FeMul(&t2, &t2, &t1) // 99..0 99 FeSquare(&t3, &t2) // 100..1 100 for i = 1; i < 100; i++ { // 199..100 101 FeSquare(&t3, &t3) 102 } 103 FeMul(&t2, &t3, &t2) // 199..0 104 FeSquare(&t2, &t2) // 200..1 105 for i = 1; i < 50; i++ { // 249..50 106 FeSquare(&t2, &t2) 107 } 108 FeMul(&t1, &t2, &t1) // 249..0 109 FeSquare(&t1, &t1) // 250..1 110 for i = 1; i < 5; i++ { // 254..5 111 FeSquare(&t1, &t1) 112 } 113 FeMul(out, &t1, &t0) // 254..5,3,1,0 114 } 115 116 func fePow22523(out, z *FieldElement) { 117 var t0, t1, t2 FieldElement 118 var i int 119 120 FeSquare(&t0, z) 121 for i = 1; i < 1; i++ { 122 FeSquare(&t0, &t0) 123 } 124 FeSquare(&t1, &t0) 125 for i = 1; i < 2; i++ { 126 FeSquare(&t1, &t1) 127 } 128 FeMul(&t1, z, &t1) 129 FeMul(&t0, &t0, &t1) 130 FeSquare(&t0, &t0) 131 for i = 1; i < 1; i++ { 132 FeSquare(&t0, &t0) 133 } 134 FeMul(&t0, &t1, &t0) 135 FeSquare(&t1, &t0) 136 for i = 1; i < 5; i++ { 137 FeSquare(&t1, &t1) 138 } 139 FeMul(&t0, &t1, &t0) 140 FeSquare(&t1, &t0) 141 for i = 1; i < 10; i++ { 142 FeSquare(&t1, &t1) 143 } 144 FeMul(&t1, &t1, &t0) 145 FeSquare(&t2, &t1) 146 for i = 1; i < 20; i++ { 147 FeSquare(&t2, &t2) 148 } 149 FeMul(&t1, &t2, &t1) 150 FeSquare(&t1, &t1) 151 for i = 1; i < 10; i++ { 152 FeSquare(&t1, &t1) 153 } 154 FeMul(&t0, &t1, &t0) 155 FeSquare(&t1, &t0) 156 for i = 1; i < 50; i++ { 157 FeSquare(&t1, &t1) 158 } 159 FeMul(&t1, &t1, &t0) 160 FeSquare(&t2, &t1) 161 for i = 1; i < 100; i++ { 162 FeSquare(&t2, &t2) 163 } 164 FeMul(&t1, &t2, &t1) 165 FeSquare(&t1, &t1) 166 for i = 1; i < 50; i++ { 167 FeSquare(&t1, &t1) 168 } 169 FeMul(&t0, &t1, &t0) 170 FeSquare(&t0, &t0) 171 for i = 1; i < 2; i++ { 172 FeSquare(&t0, &t0) 173 } 174 FeMul(out, &t0, z) 175 }