1 package x25519
2
3 import (
4 "encoding/binary"
5 "math/bits"
6
7 fp "github.com/cloudflare/circl/math/fp25519"
8 )
9
10 func doubleGeneric(x, z *fp.Elt) {
11 t0, t1 := &fp.Elt{}, &fp.Elt{}
12 fp.AddSub(x, z)
13 fp.Sqr(x, x)
14 fp.Sqr(z, z)
15 fp.Sub(t0, x, z)
16 mulA24Generic(t1, t0)
17 fp.Add(t1, t1, z)
18 fp.Mul(x, x, z)
19 fp.Mul(z, t0, t1)
20 }
21
22 func diffAddGeneric(w *[5]fp.Elt, b uint) {
23 mu, x1, z1, x2, z2 := &w[0], &w[1], &w[2], &w[3], &w[4]
24 fp.Cswap(x1, x2, b)
25 fp.Cswap(z1, z2, b)
26 fp.AddSub(x1, z1)
27 fp.Mul(z1, z1, mu)
28 fp.AddSub(x1, z1)
29 fp.Sqr(x1, x1)
30 fp.Sqr(z1, z1)
31 fp.Mul(x1, x1, z2)
32 fp.Mul(z1, z1, x2)
33 }
34
35 func ladderStepGeneric(w *[5]fp.Elt, b uint) {
36 x1, x2, z2, x3, z3 := &w[0], &w[1], &w[2], &w[3], &w[4]
37 t0 := &fp.Elt{}
38 t1 := &fp.Elt{}
39 fp.AddSub(x2, z2)
40 fp.AddSub(x3, z3)
41 fp.Mul(t0, x2, z3)
42 fp.Mul(t1, x3, z2)
43 fp.AddSub(t0, t1)
44 fp.Cmov(x2, x3, b)
45 fp.Cmov(z2, z3, b)
46 fp.Sqr(x3, t0)
47 fp.Sqr(z3, t1)
48 fp.Mul(z3, x1, z3)
49 fp.Sqr(x2, x2)
50 fp.Sqr(z2, z2)
51 fp.Sub(t0, x2, z2)
52 mulA24Generic(t1, t0)
53 fp.Add(t1, t1, z2)
54 fp.Mul(x2, x2, z2)
55 fp.Mul(z2, t0, t1)
56 }
57
58 func mulA24Generic(z, x *fp.Elt) {
59 const A24 = 121666
60 const n = 8
61 var xx [4]uint64
62 for i := range xx {
63 xx[i] = binary.LittleEndian.Uint64(x[i*n : (i+1)*n])
64 }
65
66 h0, l0 := bits.Mul64(xx[0], A24)
67 h1, l1 := bits.Mul64(xx[1], A24)
68 h2, l2 := bits.Mul64(xx[2], A24)
69 h3, l3 := bits.Mul64(xx[3], A24)
70
71 var c3 uint64
72 l1, c0 := bits.Add64(h0, l1, 0)
73 l2, c1 := bits.Add64(h1, l2, c0)
74 l3, c2 := bits.Add64(h2, l3, c1)
75 l4, _ := bits.Add64(h3, 0, c2)
76 _, l4 = bits.Mul64(l4, 38)
77 l0, c0 = bits.Add64(l0, l4, 0)
78 xx[1], c1 = bits.Add64(l1, 0, c0)
79 xx[2], c2 = bits.Add64(l2, 0, c1)
80 xx[3], c3 = bits.Add64(l3, 0, c2)
81 xx[0], _ = bits.Add64(l0, (-c3)&38, 0)
82 for i := range xx {
83 binary.LittleEndian.PutUint64(z[i*n:(i+1)*n], xx[i])
84 }
85 }
86
View as plain text