github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/crypto/internal/edwards25519/scalar.go (about) 1 // Copyright (c) 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 edwards25519 6 7 import ( 8 "crypto/subtle" 9 "encoding/binary" 10 "errors" 11 ) 12 13 // A Scalar is an integer modulo 14 // 15 // l = 2^252 + 27742317777372353535851937790883648493 16 // 17 // which is the prime order of the edwards25519 group. 18 // 19 // This type works similarly to math/big.Int, and all arguments and 20 // receivers are allowed to alias. 21 // 22 // The zero value is a valid zero element. 23 type Scalar struct { 24 // s is the Scalar value in little-endian. The value is always reduced 25 // modulo l between operations. 26 s [32]byte 27 } 28 29 var ( 30 scZero = Scalar{[32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}} 31 32 scOne = Scalar{[32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}} 33 34 scMinusOne = Scalar{[32]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}} 35 ) 36 37 // NewScalar returns a new zero Scalar. 38 func NewScalar() *Scalar { 39 return &Scalar{} 40 } 41 42 // MultiplyAdd sets s = x * y + z mod l, and returns s. 43 func (s *Scalar) MultiplyAdd(x, y, z *Scalar) *Scalar { 44 scMulAdd(&s.s, &x.s, &y.s, &z.s) 45 return s 46 } 47 48 // Add sets s = x + y mod l, and returns s. 49 func (s *Scalar) Add(x, y *Scalar) *Scalar { 50 // s = 1 * x + y mod l 51 scMulAdd(&s.s, &scOne.s, &x.s, &y.s) 52 return s 53 } 54 55 // Subtract sets s = x - y mod l, and returns s. 56 func (s *Scalar) Subtract(x, y *Scalar) *Scalar { 57 // s = -1 * y + x mod l 58 scMulAdd(&s.s, &scMinusOne.s, &y.s, &x.s) 59 return s 60 } 61 62 // Negate sets s = -x mod l, and returns s. 63 func (s *Scalar) Negate(x *Scalar) *Scalar { 64 // s = -1 * x + 0 mod l 65 scMulAdd(&s.s, &scMinusOne.s, &x.s, &scZero.s) 66 return s 67 } 68 69 // Multiply sets s = x * y mod l, and returns s. 70 func (s *Scalar) Multiply(x, y *Scalar) *Scalar { 71 // s = x * y + 0 mod l 72 scMulAdd(&s.s, &x.s, &y.s, &scZero.s) 73 return s 74 } 75 76 // Set sets s = x, and returns s. 77 func (s *Scalar) Set(x *Scalar) *Scalar { 78 *s = *x 79 return s 80 } 81 82 // SetUniformBytes sets s = x mod l, where x is a 64-byte little-endian integer. 83 // If x is not of the right length, SetUniformBytes returns nil and an error, 84 // and the receiver is unchanged. 85 // 86 // SetUniformBytes can be used to set s to an uniformly distributed value given 87 // 64 uniformly distributed random bytes. 88 func (s *Scalar) SetUniformBytes(x []byte) (*Scalar, error) { 89 if len(x) != 64 { 90 return nil, errors.New("edwards25519: invalid SetUniformBytes input length") 91 } 92 var wideBytes [64]byte 93 copy(wideBytes[:], x[:]) 94 scReduce(&s.s, &wideBytes) 95 return s, nil 96 } 97 98 // SetCanonicalBytes sets s = x, where x is a 32-byte little-endian encoding of 99 // s, and returns s. If x is not a canonical encoding of s, SetCanonicalBytes 100 // returns nil and an error, and the receiver is unchanged. 101 func (s *Scalar) SetCanonicalBytes(x []byte) (*Scalar, error) { 102 if len(x) != 32 { 103 return nil, errors.New("invalid scalar length") 104 } 105 ss := &Scalar{} 106 copy(ss.s[:], x) 107 if !isReduced(ss) { 108 return nil, errors.New("invalid scalar encoding") 109 } 110 s.s = ss.s 111 return s, nil 112 } 113 114 // isReduced returns whether the given scalar is reduced modulo l. 115 func isReduced(s *Scalar) bool { 116 for i := len(s.s) - 1; i >= 0; i-- { 117 switch { 118 case s.s[i] > scMinusOne.s[i]: 119 return false 120 case s.s[i] < scMinusOne.s[i]: 121 return true 122 } 123 } 124 return true 125 } 126 127 // SetBytesWithClamping applies the buffer pruning described in RFC 8032, 128 // Section 5.1.5 (also known as clamping) and sets s to the result. The input 129 // must be 32 bytes, and it is not modified. If x is not of the right length, 130 // SetBytesWithClamping returns nil and an error, and the receiver is unchanged. 131 // 132 // Note that since Scalar values are always reduced modulo the prime order of 133 // the curve, the resulting value will not preserve any of the cofactor-clearing 134 // properties that clamping is meant to provide. It will however work as 135 // expected as long as it is applied to points on the prime order subgroup, like 136 // in Ed25519. In fact, it is lost to history why RFC 8032 adopted the 137 // irrelevant RFC 7748 clamping, but it is now required for compatibility. 138 func (s *Scalar) SetBytesWithClamping(x []byte) (*Scalar, error) { 139 // The description above omits the purpose of the high bits of the clamping 140 // for brevity, but those are also lost to reductions, and are also 141 // irrelevant to edwards25519 as they protect against a specific 142 // implementation bug that was once observed in a generic Montgomery ladder. 143 if len(x) != 32 { 144 return nil, errors.New("edwards25519: invalid SetBytesWithClamping input length") 145 } 146 var wideBytes [64]byte 147 copy(wideBytes[:], x[:]) 148 wideBytes[0] &= 248 149 wideBytes[31] &= 63 150 wideBytes[31] |= 64 151 scReduce(&s.s, &wideBytes) 152 return s, nil 153 } 154 155 // Bytes returns the canonical 32-byte little-endian encoding of s. 156 func (s *Scalar) Bytes() []byte { 157 buf := make([]byte, 32) 158 copy(buf, s.s[:]) 159 return buf 160 } 161 162 // Equal returns 1 if s and t are equal, and 0 otherwise. 163 func (s *Scalar) Equal(t *Scalar) int { 164 return subtle.ConstantTimeCompare(s.s[:], t.s[:]) 165 } 166 167 // scMulAdd and scReduce are ported from the public domain, “ref10” 168 // implementation of ed25519 from SUPERCOP. 169 170 func load3(in []byte) int64 { 171 r := int64(in[0]) 172 r |= int64(in[1]) << 8 173 r |= int64(in[2]) << 16 174 return r 175 } 176 177 func load4(in []byte) int64 { 178 r := int64(in[0]) 179 r |= int64(in[1]) << 8 180 r |= int64(in[2]) << 16 181 r |= int64(in[3]) << 24 182 return r 183 } 184 185 // Input: 186 // 187 // a[0]+256*a[1]+...+256^31*a[31] = a 188 // b[0]+256*b[1]+...+256^31*b[31] = b 189 // c[0]+256*c[1]+...+256^31*c[31] = c 190 // 191 // Output: 192 // 193 // s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l 194 // where l = 2^252 + 27742317777372353535851937790883648493. 195 func scMulAdd(s, a, b, c *[32]byte) { 196 a0 := 2097151 & load3(a[:]) 197 a1 := 2097151 & (load4(a[2:]) >> 5) 198 a2 := 2097151 & (load3(a[5:]) >> 2) 199 a3 := 2097151 & (load4(a[7:]) >> 7) 200 a4 := 2097151 & (load4(a[10:]) >> 4) 201 a5 := 2097151 & (load3(a[13:]) >> 1) 202 a6 := 2097151 & (load4(a[15:]) >> 6) 203 a7 := 2097151 & (load3(a[18:]) >> 3) 204 a8 := 2097151 & load3(a[21:]) 205 a9 := 2097151 & (load4(a[23:]) >> 5) 206 a10 := 2097151 & (load3(a[26:]) >> 2) 207 a11 := (load4(a[28:]) >> 7) 208 b0 := 2097151 & load3(b[:]) 209 b1 := 2097151 & (load4(b[2:]) >> 5) 210 b2 := 2097151 & (load3(b[5:]) >> 2) 211 b3 := 2097151 & (load4(b[7:]) >> 7) 212 b4 := 2097151 & (load4(b[10:]) >> 4) 213 b5 := 2097151 & (load3(b[13:]) >> 1) 214 b6 := 2097151 & (load4(b[15:]) >> 6) 215 b7 := 2097151 & (load3(b[18:]) >> 3) 216 b8 := 2097151 & load3(b[21:]) 217 b9 := 2097151 & (load4(b[23:]) >> 5) 218 b10 := 2097151 & (load3(b[26:]) >> 2) 219 b11 := (load4(b[28:]) >> 7) 220 c0 := 2097151 & load3(c[:]) 221 c1 := 2097151 & (load4(c[2:]) >> 5) 222 c2 := 2097151 & (load3(c[5:]) >> 2) 223 c3 := 2097151 & (load4(c[7:]) >> 7) 224 c4 := 2097151 & (load4(c[10:]) >> 4) 225 c5 := 2097151 & (load3(c[13:]) >> 1) 226 c6 := 2097151 & (load4(c[15:]) >> 6) 227 c7 := 2097151 & (load3(c[18:]) >> 3) 228 c8 := 2097151 & load3(c[21:]) 229 c9 := 2097151 & (load4(c[23:]) >> 5) 230 c10 := 2097151 & (load3(c[26:]) >> 2) 231 c11 := (load4(c[28:]) >> 7) 232 var carry [23]int64 233 234 s0 := c0 + a0*b0 235 s1 := c1 + a0*b1 + a1*b0 236 s2 := c2 + a0*b2 + a1*b1 + a2*b0 237 s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 238 s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 239 s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 240 s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 241 s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 242 s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 243 s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 244 s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 245 s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 246 s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 247 s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 248 s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 249 s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 250 s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 251 s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 252 s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 253 s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8 254 s20 := a9*b11 + a10*b10 + a11*b9 255 s21 := a10*b11 + a11*b10 256 s22 := a11 * b11 257 s23 := int64(0) 258 259 carry[0] = (s0 + (1 << 20)) >> 21 260 s1 += carry[0] 261 s0 -= carry[0] << 21 262 carry[2] = (s2 + (1 << 20)) >> 21 263 s3 += carry[2] 264 s2 -= carry[2] << 21 265 carry[4] = (s4 + (1 << 20)) >> 21 266 s5 += carry[4] 267 s4 -= carry[4] << 21 268 carry[6] = (s6 + (1 << 20)) >> 21 269 s7 += carry[6] 270 s6 -= carry[6] << 21 271 carry[8] = (s8 + (1 << 20)) >> 21 272 s9 += carry[8] 273 s8 -= carry[8] << 21 274 carry[10] = (s10 + (1 << 20)) >> 21 275 s11 += carry[10] 276 s10 -= carry[10] << 21 277 carry[12] = (s12 + (1 << 20)) >> 21 278 s13 += carry[12] 279 s12 -= carry[12] << 21 280 carry[14] = (s14 + (1 << 20)) >> 21 281 s15 += carry[14] 282 s14 -= carry[14] << 21 283 carry[16] = (s16 + (1 << 20)) >> 21 284 s17 += carry[16] 285 s16 -= carry[16] << 21 286 carry[18] = (s18 + (1 << 20)) >> 21 287 s19 += carry[18] 288 s18 -= carry[18] << 21 289 carry[20] = (s20 + (1 << 20)) >> 21 290 s21 += carry[20] 291 s20 -= carry[20] << 21 292 carry[22] = (s22 + (1 << 20)) >> 21 293 s23 += carry[22] 294 s22 -= carry[22] << 21 295 296 carry[1] = (s1 + (1 << 20)) >> 21 297 s2 += carry[1] 298 s1 -= carry[1] << 21 299 carry[3] = (s3 + (1 << 20)) >> 21 300 s4 += carry[3] 301 s3 -= carry[3] << 21 302 carry[5] = (s5 + (1 << 20)) >> 21 303 s6 += carry[5] 304 s5 -= carry[5] << 21 305 carry[7] = (s7 + (1 << 20)) >> 21 306 s8 += carry[7] 307 s7 -= carry[7] << 21 308 carry[9] = (s9 + (1 << 20)) >> 21 309 s10 += carry[9] 310 s9 -= carry[9] << 21 311 carry[11] = (s11 + (1 << 20)) >> 21 312 s12 += carry[11] 313 s11 -= carry[11] << 21 314 carry[13] = (s13 + (1 << 20)) >> 21 315 s14 += carry[13] 316 s13 -= carry[13] << 21 317 carry[15] = (s15 + (1 << 20)) >> 21 318 s16 += carry[15] 319 s15 -= carry[15] << 21 320 carry[17] = (s17 + (1 << 20)) >> 21 321 s18 += carry[17] 322 s17 -= carry[17] << 21 323 carry[19] = (s19 + (1 << 20)) >> 21 324 s20 += carry[19] 325 s19 -= carry[19] << 21 326 carry[21] = (s21 + (1 << 20)) >> 21 327 s22 += carry[21] 328 s21 -= carry[21] << 21 329 330 s11 += s23 * 666643 331 s12 += s23 * 470296 332 s13 += s23 * 654183 333 s14 -= s23 * 997805 334 s15 += s23 * 136657 335 s16 -= s23 * 683901 336 s23 = 0 337 338 s10 += s22 * 666643 339 s11 += s22 * 470296 340 s12 += s22 * 654183 341 s13 -= s22 * 997805 342 s14 += s22 * 136657 343 s15 -= s22 * 683901 344 s22 = 0 345 346 s9 += s21 * 666643 347 s10 += s21 * 470296 348 s11 += s21 * 654183 349 s12 -= s21 * 997805 350 s13 += s21 * 136657 351 s14 -= s21 * 683901 352 s21 = 0 353 354 s8 += s20 * 666643 355 s9 += s20 * 470296 356 s10 += s20 * 654183 357 s11 -= s20 * 997805 358 s12 += s20 * 136657 359 s13 -= s20 * 683901 360 s20 = 0 361 362 s7 += s19 * 666643 363 s8 += s19 * 470296 364 s9 += s19 * 654183 365 s10 -= s19 * 997805 366 s11 += s19 * 136657 367 s12 -= s19 * 683901 368 s19 = 0 369 370 s6 += s18 * 666643 371 s7 += s18 * 470296 372 s8 += s18 * 654183 373 s9 -= s18 * 997805 374 s10 += s18 * 136657 375 s11 -= s18 * 683901 376 s18 = 0 377 378 carry[6] = (s6 + (1 << 20)) >> 21 379 s7 += carry[6] 380 s6 -= carry[6] << 21 381 carry[8] = (s8 + (1 << 20)) >> 21 382 s9 += carry[8] 383 s8 -= carry[8] << 21 384 carry[10] = (s10 + (1 << 20)) >> 21 385 s11 += carry[10] 386 s10 -= carry[10] << 21 387 carry[12] = (s12 + (1 << 20)) >> 21 388 s13 += carry[12] 389 s12 -= carry[12] << 21 390 carry[14] = (s14 + (1 << 20)) >> 21 391 s15 += carry[14] 392 s14 -= carry[14] << 21 393 carry[16] = (s16 + (1 << 20)) >> 21 394 s17 += carry[16] 395 s16 -= carry[16] << 21 396 397 carry[7] = (s7 + (1 << 20)) >> 21 398 s8 += carry[7] 399 s7 -= carry[7] << 21 400 carry[9] = (s9 + (1 << 20)) >> 21 401 s10 += carry[9] 402 s9 -= carry[9] << 21 403 carry[11] = (s11 + (1 << 20)) >> 21 404 s12 += carry[11] 405 s11 -= carry[11] << 21 406 carry[13] = (s13 + (1 << 20)) >> 21 407 s14 += carry[13] 408 s13 -= carry[13] << 21 409 carry[15] = (s15 + (1 << 20)) >> 21 410 s16 += carry[15] 411 s15 -= carry[15] << 21 412 413 s5 += s17 * 666643 414 s6 += s17 * 470296 415 s7 += s17 * 654183 416 s8 -= s17 * 997805 417 s9 += s17 * 136657 418 s10 -= s17 * 683901 419 s17 = 0 420 421 s4 += s16 * 666643 422 s5 += s16 * 470296 423 s6 += s16 * 654183 424 s7 -= s16 * 997805 425 s8 += s16 * 136657 426 s9 -= s16 * 683901 427 s16 = 0 428 429 s3 += s15 * 666643 430 s4 += s15 * 470296 431 s5 += s15 * 654183 432 s6 -= s15 * 997805 433 s7 += s15 * 136657 434 s8 -= s15 * 683901 435 s15 = 0 436 437 s2 += s14 * 666643 438 s3 += s14 * 470296 439 s4 += s14 * 654183 440 s5 -= s14 * 997805 441 s6 += s14 * 136657 442 s7 -= s14 * 683901 443 s14 = 0 444 445 s1 += s13 * 666643 446 s2 += s13 * 470296 447 s3 += s13 * 654183 448 s4 -= s13 * 997805 449 s5 += s13 * 136657 450 s6 -= s13 * 683901 451 s13 = 0 452 453 s0 += s12 * 666643 454 s1 += s12 * 470296 455 s2 += s12 * 654183 456 s3 -= s12 * 997805 457 s4 += s12 * 136657 458 s5 -= s12 * 683901 459 s12 = 0 460 461 carry[0] = (s0 + (1 << 20)) >> 21 462 s1 += carry[0] 463 s0 -= carry[0] << 21 464 carry[2] = (s2 + (1 << 20)) >> 21 465 s3 += carry[2] 466 s2 -= carry[2] << 21 467 carry[4] = (s4 + (1 << 20)) >> 21 468 s5 += carry[4] 469 s4 -= carry[4] << 21 470 carry[6] = (s6 + (1 << 20)) >> 21 471 s7 += carry[6] 472 s6 -= carry[6] << 21 473 carry[8] = (s8 + (1 << 20)) >> 21 474 s9 += carry[8] 475 s8 -= carry[8] << 21 476 carry[10] = (s10 + (1 << 20)) >> 21 477 s11 += carry[10] 478 s10 -= carry[10] << 21 479 480 carry[1] = (s1 + (1 << 20)) >> 21 481 s2 += carry[1] 482 s1 -= carry[1] << 21 483 carry[3] = (s3 + (1 << 20)) >> 21 484 s4 += carry[3] 485 s3 -= carry[3] << 21 486 carry[5] = (s5 + (1 << 20)) >> 21 487 s6 += carry[5] 488 s5 -= carry[5] << 21 489 carry[7] = (s7 + (1 << 20)) >> 21 490 s8 += carry[7] 491 s7 -= carry[7] << 21 492 carry[9] = (s9 + (1 << 20)) >> 21 493 s10 += carry[9] 494 s9 -= carry[9] << 21 495 carry[11] = (s11 + (1 << 20)) >> 21 496 s12 += carry[11] 497 s11 -= carry[11] << 21 498 499 s0 += s12 * 666643 500 s1 += s12 * 470296 501 s2 += s12 * 654183 502 s3 -= s12 * 997805 503 s4 += s12 * 136657 504 s5 -= s12 * 683901 505 s12 = 0 506 507 carry[0] = s0 >> 21 508 s1 += carry[0] 509 s0 -= carry[0] << 21 510 carry[1] = s1 >> 21 511 s2 += carry[1] 512 s1 -= carry[1] << 21 513 carry[2] = s2 >> 21 514 s3 += carry[2] 515 s2 -= carry[2] << 21 516 carry[3] = s3 >> 21 517 s4 += carry[3] 518 s3 -= carry[3] << 21 519 carry[4] = s4 >> 21 520 s5 += carry[4] 521 s4 -= carry[4] << 21 522 carry[5] = s5 >> 21 523 s6 += carry[5] 524 s5 -= carry[5] << 21 525 carry[6] = s6 >> 21 526 s7 += carry[6] 527 s6 -= carry[6] << 21 528 carry[7] = s7 >> 21 529 s8 += carry[7] 530 s7 -= carry[7] << 21 531 carry[8] = s8 >> 21 532 s9 += carry[8] 533 s8 -= carry[8] << 21 534 carry[9] = s9 >> 21 535 s10 += carry[9] 536 s9 -= carry[9] << 21 537 carry[10] = s10 >> 21 538 s11 += carry[10] 539 s10 -= carry[10] << 21 540 carry[11] = s11 >> 21 541 s12 += carry[11] 542 s11 -= carry[11] << 21 543 544 s0 += s12 * 666643 545 s1 += s12 * 470296 546 s2 += s12 * 654183 547 s3 -= s12 * 997805 548 s4 += s12 * 136657 549 s5 -= s12 * 683901 550 s12 = 0 551 552 carry[0] = s0 >> 21 553 s1 += carry[0] 554 s0 -= carry[0] << 21 555 carry[1] = s1 >> 21 556 s2 += carry[1] 557 s1 -= carry[1] << 21 558 carry[2] = s2 >> 21 559 s3 += carry[2] 560 s2 -= carry[2] << 21 561 carry[3] = s3 >> 21 562 s4 += carry[3] 563 s3 -= carry[3] << 21 564 carry[4] = s4 >> 21 565 s5 += carry[4] 566 s4 -= carry[4] << 21 567 carry[5] = s5 >> 21 568 s6 += carry[5] 569 s5 -= carry[5] << 21 570 carry[6] = s6 >> 21 571 s7 += carry[6] 572 s6 -= carry[6] << 21 573 carry[7] = s7 >> 21 574 s8 += carry[7] 575 s7 -= carry[7] << 21 576 carry[8] = s8 >> 21 577 s9 += carry[8] 578 s8 -= carry[8] << 21 579 carry[9] = s9 >> 21 580 s10 += carry[9] 581 s9 -= carry[9] << 21 582 carry[10] = s10 >> 21 583 s11 += carry[10] 584 s10 -= carry[10] << 21 585 586 s[0] = byte(s0 >> 0) 587 s[1] = byte(s0 >> 8) 588 s[2] = byte((s0 >> 16) | (s1 << 5)) 589 s[3] = byte(s1 >> 3) 590 s[4] = byte(s1 >> 11) 591 s[5] = byte((s1 >> 19) | (s2 << 2)) 592 s[6] = byte(s2 >> 6) 593 s[7] = byte((s2 >> 14) | (s3 << 7)) 594 s[8] = byte(s3 >> 1) 595 s[9] = byte(s3 >> 9) 596 s[10] = byte((s3 >> 17) | (s4 << 4)) 597 s[11] = byte(s4 >> 4) 598 s[12] = byte(s4 >> 12) 599 s[13] = byte((s4 >> 20) | (s5 << 1)) 600 s[14] = byte(s5 >> 7) 601 s[15] = byte((s5 >> 15) | (s6 << 6)) 602 s[16] = byte(s6 >> 2) 603 s[17] = byte(s6 >> 10) 604 s[18] = byte((s6 >> 18) | (s7 << 3)) 605 s[19] = byte(s7 >> 5) 606 s[20] = byte(s7 >> 13) 607 s[21] = byte(s8 >> 0) 608 s[22] = byte(s8 >> 8) 609 s[23] = byte((s8 >> 16) | (s9 << 5)) 610 s[24] = byte(s9 >> 3) 611 s[25] = byte(s9 >> 11) 612 s[26] = byte((s9 >> 19) | (s10 << 2)) 613 s[27] = byte(s10 >> 6) 614 s[28] = byte((s10 >> 14) | (s11 << 7)) 615 s[29] = byte(s11 >> 1) 616 s[30] = byte(s11 >> 9) 617 s[31] = byte(s11 >> 17) 618 } 619 620 // Input: 621 // 622 // s[0]+256*s[1]+...+256^63*s[63] = s 623 // 624 // Output: 625 // 626 // s[0]+256*s[1]+...+256^31*s[31] = s mod l 627 // where l = 2^252 + 27742317777372353535851937790883648493. 628 func scReduce(out *[32]byte, s *[64]byte) { 629 s0 := 2097151 & load3(s[:]) 630 s1 := 2097151 & (load4(s[2:]) >> 5) 631 s2 := 2097151 & (load3(s[5:]) >> 2) 632 s3 := 2097151 & (load4(s[7:]) >> 7) 633 s4 := 2097151 & (load4(s[10:]) >> 4) 634 s5 := 2097151 & (load3(s[13:]) >> 1) 635 s6 := 2097151 & (load4(s[15:]) >> 6) 636 s7 := 2097151 & (load3(s[18:]) >> 3) 637 s8 := 2097151 & load3(s[21:]) 638 s9 := 2097151 & (load4(s[23:]) >> 5) 639 s10 := 2097151 & (load3(s[26:]) >> 2) 640 s11 := 2097151 & (load4(s[28:]) >> 7) 641 s12 := 2097151 & (load4(s[31:]) >> 4) 642 s13 := 2097151 & (load3(s[34:]) >> 1) 643 s14 := 2097151 & (load4(s[36:]) >> 6) 644 s15 := 2097151 & (load3(s[39:]) >> 3) 645 s16 := 2097151 & load3(s[42:]) 646 s17 := 2097151 & (load4(s[44:]) >> 5) 647 s18 := 2097151 & (load3(s[47:]) >> 2) 648 s19 := 2097151 & (load4(s[49:]) >> 7) 649 s20 := 2097151 & (load4(s[52:]) >> 4) 650 s21 := 2097151 & (load3(s[55:]) >> 1) 651 s22 := 2097151 & (load4(s[57:]) >> 6) 652 s23 := (load4(s[60:]) >> 3) 653 654 s11 += s23 * 666643 655 s12 += s23 * 470296 656 s13 += s23 * 654183 657 s14 -= s23 * 997805 658 s15 += s23 * 136657 659 s16 -= s23 * 683901 660 s23 = 0 661 662 s10 += s22 * 666643 663 s11 += s22 * 470296 664 s12 += s22 * 654183 665 s13 -= s22 * 997805 666 s14 += s22 * 136657 667 s15 -= s22 * 683901 668 s22 = 0 669 670 s9 += s21 * 666643 671 s10 += s21 * 470296 672 s11 += s21 * 654183 673 s12 -= s21 * 997805 674 s13 += s21 * 136657 675 s14 -= s21 * 683901 676 s21 = 0 677 678 s8 += s20 * 666643 679 s9 += s20 * 470296 680 s10 += s20 * 654183 681 s11 -= s20 * 997805 682 s12 += s20 * 136657 683 s13 -= s20 * 683901 684 s20 = 0 685 686 s7 += s19 * 666643 687 s8 += s19 * 470296 688 s9 += s19 * 654183 689 s10 -= s19 * 997805 690 s11 += s19 * 136657 691 s12 -= s19 * 683901 692 s19 = 0 693 694 s6 += s18 * 666643 695 s7 += s18 * 470296 696 s8 += s18 * 654183 697 s9 -= s18 * 997805 698 s10 += s18 * 136657 699 s11 -= s18 * 683901 700 s18 = 0 701 702 var carry [17]int64 703 704 carry[6] = (s6 + (1 << 20)) >> 21 705 s7 += carry[6] 706 s6 -= carry[6] << 21 707 carry[8] = (s8 + (1 << 20)) >> 21 708 s9 += carry[8] 709 s8 -= carry[8] << 21 710 carry[10] = (s10 + (1 << 20)) >> 21 711 s11 += carry[10] 712 s10 -= carry[10] << 21 713 carry[12] = (s12 + (1 << 20)) >> 21 714 s13 += carry[12] 715 s12 -= carry[12] << 21 716 carry[14] = (s14 + (1 << 20)) >> 21 717 s15 += carry[14] 718 s14 -= carry[14] << 21 719 carry[16] = (s16 + (1 << 20)) >> 21 720 s17 += carry[16] 721 s16 -= carry[16] << 21 722 723 carry[7] = (s7 + (1 << 20)) >> 21 724 s8 += carry[7] 725 s7 -= carry[7] << 21 726 carry[9] = (s9 + (1 << 20)) >> 21 727 s10 += carry[9] 728 s9 -= carry[9] << 21 729 carry[11] = (s11 + (1 << 20)) >> 21 730 s12 += carry[11] 731 s11 -= carry[11] << 21 732 carry[13] = (s13 + (1 << 20)) >> 21 733 s14 += carry[13] 734 s13 -= carry[13] << 21 735 carry[15] = (s15 + (1 << 20)) >> 21 736 s16 += carry[15] 737 s15 -= carry[15] << 21 738 739 s5 += s17 * 666643 740 s6 += s17 * 470296 741 s7 += s17 * 654183 742 s8 -= s17 * 997805 743 s9 += s17 * 136657 744 s10 -= s17 * 683901 745 s17 = 0 746 747 s4 += s16 * 666643 748 s5 += s16 * 470296 749 s6 += s16 * 654183 750 s7 -= s16 * 997805 751 s8 += s16 * 136657 752 s9 -= s16 * 683901 753 s16 = 0 754 755 s3 += s15 * 666643 756 s4 += s15 * 470296 757 s5 += s15 * 654183 758 s6 -= s15 * 997805 759 s7 += s15 * 136657 760 s8 -= s15 * 683901 761 s15 = 0 762 763 s2 += s14 * 666643 764 s3 += s14 * 470296 765 s4 += s14 * 654183 766 s5 -= s14 * 997805 767 s6 += s14 * 136657 768 s7 -= s14 * 683901 769 s14 = 0 770 771 s1 += s13 * 666643 772 s2 += s13 * 470296 773 s3 += s13 * 654183 774 s4 -= s13 * 997805 775 s5 += s13 * 136657 776 s6 -= s13 * 683901 777 s13 = 0 778 779 s0 += s12 * 666643 780 s1 += s12 * 470296 781 s2 += s12 * 654183 782 s3 -= s12 * 997805 783 s4 += s12 * 136657 784 s5 -= s12 * 683901 785 s12 = 0 786 787 carry[0] = (s0 + (1 << 20)) >> 21 788 s1 += carry[0] 789 s0 -= carry[0] << 21 790 carry[2] = (s2 + (1 << 20)) >> 21 791 s3 += carry[2] 792 s2 -= carry[2] << 21 793 carry[4] = (s4 + (1 << 20)) >> 21 794 s5 += carry[4] 795 s4 -= carry[4] << 21 796 carry[6] = (s6 + (1 << 20)) >> 21 797 s7 += carry[6] 798 s6 -= carry[6] << 21 799 carry[8] = (s8 + (1 << 20)) >> 21 800 s9 += carry[8] 801 s8 -= carry[8] << 21 802 carry[10] = (s10 + (1 << 20)) >> 21 803 s11 += carry[10] 804 s10 -= carry[10] << 21 805 806 carry[1] = (s1 + (1 << 20)) >> 21 807 s2 += carry[1] 808 s1 -= carry[1] << 21 809 carry[3] = (s3 + (1 << 20)) >> 21 810 s4 += carry[3] 811 s3 -= carry[3] << 21 812 carry[5] = (s5 + (1 << 20)) >> 21 813 s6 += carry[5] 814 s5 -= carry[5] << 21 815 carry[7] = (s7 + (1 << 20)) >> 21 816 s8 += carry[7] 817 s7 -= carry[7] << 21 818 carry[9] = (s9 + (1 << 20)) >> 21 819 s10 += carry[9] 820 s9 -= carry[9] << 21 821 carry[11] = (s11 + (1 << 20)) >> 21 822 s12 += carry[11] 823 s11 -= carry[11] << 21 824 825 s0 += s12 * 666643 826 s1 += s12 * 470296 827 s2 += s12 * 654183 828 s3 -= s12 * 997805 829 s4 += s12 * 136657 830 s5 -= s12 * 683901 831 s12 = 0 832 833 carry[0] = s0 >> 21 834 s1 += carry[0] 835 s0 -= carry[0] << 21 836 carry[1] = s1 >> 21 837 s2 += carry[1] 838 s1 -= carry[1] << 21 839 carry[2] = s2 >> 21 840 s3 += carry[2] 841 s2 -= carry[2] << 21 842 carry[3] = s3 >> 21 843 s4 += carry[3] 844 s3 -= carry[3] << 21 845 carry[4] = s4 >> 21 846 s5 += carry[4] 847 s4 -= carry[4] << 21 848 carry[5] = s5 >> 21 849 s6 += carry[5] 850 s5 -= carry[5] << 21 851 carry[6] = s6 >> 21 852 s7 += carry[6] 853 s6 -= carry[6] << 21 854 carry[7] = s7 >> 21 855 s8 += carry[7] 856 s7 -= carry[7] << 21 857 carry[8] = s8 >> 21 858 s9 += carry[8] 859 s8 -= carry[8] << 21 860 carry[9] = s9 >> 21 861 s10 += carry[9] 862 s9 -= carry[9] << 21 863 carry[10] = s10 >> 21 864 s11 += carry[10] 865 s10 -= carry[10] << 21 866 carry[11] = s11 >> 21 867 s12 += carry[11] 868 s11 -= carry[11] << 21 869 870 s0 += s12 * 666643 871 s1 += s12 * 470296 872 s2 += s12 * 654183 873 s3 -= s12 * 997805 874 s4 += s12 * 136657 875 s5 -= s12 * 683901 876 s12 = 0 877 878 carry[0] = s0 >> 21 879 s1 += carry[0] 880 s0 -= carry[0] << 21 881 carry[1] = s1 >> 21 882 s2 += carry[1] 883 s1 -= carry[1] << 21 884 carry[2] = s2 >> 21 885 s3 += carry[2] 886 s2 -= carry[2] << 21 887 carry[3] = s3 >> 21 888 s4 += carry[3] 889 s3 -= carry[3] << 21 890 carry[4] = s4 >> 21 891 s5 += carry[4] 892 s4 -= carry[4] << 21 893 carry[5] = s5 >> 21 894 s6 += carry[5] 895 s5 -= carry[5] << 21 896 carry[6] = s6 >> 21 897 s7 += carry[6] 898 s6 -= carry[6] << 21 899 carry[7] = s7 >> 21 900 s8 += carry[7] 901 s7 -= carry[7] << 21 902 carry[8] = s8 >> 21 903 s9 += carry[8] 904 s8 -= carry[8] << 21 905 carry[9] = s9 >> 21 906 s10 += carry[9] 907 s9 -= carry[9] << 21 908 carry[10] = s10 >> 21 909 s11 += carry[10] 910 s10 -= carry[10] << 21 911 912 out[0] = byte(s0 >> 0) 913 out[1] = byte(s0 >> 8) 914 out[2] = byte((s0 >> 16) | (s1 << 5)) 915 out[3] = byte(s1 >> 3) 916 out[4] = byte(s1 >> 11) 917 out[5] = byte((s1 >> 19) | (s2 << 2)) 918 out[6] = byte(s2 >> 6) 919 out[7] = byte((s2 >> 14) | (s3 << 7)) 920 out[8] = byte(s3 >> 1) 921 out[9] = byte(s3 >> 9) 922 out[10] = byte((s3 >> 17) | (s4 << 4)) 923 out[11] = byte(s4 >> 4) 924 out[12] = byte(s4 >> 12) 925 out[13] = byte((s4 >> 20) | (s5 << 1)) 926 out[14] = byte(s5 >> 7) 927 out[15] = byte((s5 >> 15) | (s6 << 6)) 928 out[16] = byte(s6 >> 2) 929 out[17] = byte(s6 >> 10) 930 out[18] = byte((s6 >> 18) | (s7 << 3)) 931 out[19] = byte(s7 >> 5) 932 out[20] = byte(s7 >> 13) 933 out[21] = byte(s8 >> 0) 934 out[22] = byte(s8 >> 8) 935 out[23] = byte((s8 >> 16) | (s9 << 5)) 936 out[24] = byte(s9 >> 3) 937 out[25] = byte(s9 >> 11) 938 out[26] = byte((s9 >> 19) | (s10 << 2)) 939 out[27] = byte(s10 >> 6) 940 out[28] = byte((s10 >> 14) | (s11 << 7)) 941 out[29] = byte(s11 >> 1) 942 out[30] = byte(s11 >> 9) 943 out[31] = byte(s11 >> 17) 944 } 945 946 // nonAdjacentForm computes a width-w non-adjacent form for this scalar. 947 // 948 // w must be between 2 and 8, or nonAdjacentForm will panic. 949 func (s *Scalar) nonAdjacentForm(w uint) [256]int8 { 950 // This implementation is adapted from the one 951 // in curve25519-dalek and is documented there: 952 // https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871 953 if s.s[31] > 127 { 954 panic("scalar has high bit set illegally") 955 } 956 if w < 2 { 957 panic("w must be at least 2 by the definition of NAF") 958 } else if w > 8 { 959 panic("NAF digits must fit in int8") 960 } 961 962 var naf [256]int8 963 var digits [5]uint64 964 965 for i := 0; i < 4; i++ { 966 digits[i] = binary.LittleEndian.Uint64(s.s[i*8:]) 967 } 968 969 width := uint64(1 << w) 970 windowMask := uint64(width - 1) 971 972 pos := uint(0) 973 carry := uint64(0) 974 for pos < 256 { 975 indexU64 := pos / 64 976 indexBit := pos % 64 977 var bitBuf uint64 978 if indexBit < 64-w { 979 // This window's bits are contained in a single u64 980 bitBuf = digits[indexU64] >> indexBit 981 } else { 982 // Combine the current 64 bits with bits from the next 64 983 bitBuf = (digits[indexU64] >> indexBit) | (digits[1+indexU64] << (64 - indexBit)) 984 } 985 986 // Add carry into the current window 987 window := carry + (bitBuf & windowMask) 988 989 if window&1 == 0 { 990 // If the window value is even, preserve the carry and continue. 991 // Why is the carry preserved? 992 // If carry == 0 and window & 1 == 0, 993 // then the next carry should be 0 994 // If carry == 1 and window & 1 == 0, 995 // then bit_buf & 1 == 1 so the next carry should be 1 996 pos += 1 997 continue 998 } 999 1000 if window < width/2 { 1001 carry = 0 1002 naf[pos] = int8(window) 1003 } else { 1004 carry = 1 1005 naf[pos] = int8(window) - int8(width) 1006 } 1007 1008 pos += w 1009 } 1010 return naf 1011 } 1012 1013 func (s *Scalar) signedRadix16() [64]int8 { 1014 if s.s[31] > 127 { 1015 panic("scalar has high bit set illegally") 1016 } 1017 1018 var digits [64]int8 1019 1020 // Compute unsigned radix-16 digits: 1021 for i := 0; i < 32; i++ { 1022 digits[2*i] = int8(s.s[i] & 15) 1023 digits[2*i+1] = int8((s.s[i] >> 4) & 15) 1024 } 1025 1026 // Recenter coefficients: 1027 for i := 0; i < 63; i++ { 1028 carry := (digits[i] + 8) >> 4 1029 digits[i] -= carry << 4 1030 digits[i+1] += carry 1031 } 1032 1033 return digits 1034 }