package curve25519
import "encoding/binary"
type fieldElement [10 ]int32
func feZero (fe *fieldElement ) {
for i := range fe {
fe [i ] = 0
}
}
func feOne (fe *fieldElement ) {
feZero (fe )
fe [0 ] = 1
}
func feAdd (dst , a , b *fieldElement ) {
for i := range dst {
dst [i ] = a [i ] + b [i ]
}
}
func feSub (dst , a , b *fieldElement ) {
for i := range dst {
dst [i ] = a [i ] - b [i ]
}
}
func feCopy (dst , src *fieldElement ) {
for i := range dst {
dst [i ] = src [i ]
}
}
func feCSwap (f , g *fieldElement , b int32 ) {
b = -b
for i := range f {
t := b & (f [i ] ^ g [i ])
f [i ] ^= t
g [i ] ^= t
}
}
func load3 (in []byte ) int64 {
var r int64
r = int64 (in [0 ])
r |= int64 (in [1 ]) << 8
r |= int64 (in [2 ]) << 16
return r
}
func load4 (in []byte ) int64 {
return int64 (binary .LittleEndian .Uint32 (in ))
}
func feFromBytes (dst *fieldElement , src *[32 ]byte ) {
h0 := load4 (src [:])
h1 := load3 (src [4 :]) << 6
h2 := load3 (src [7 :]) << 5
h3 := load3 (src [10 :]) << 3
h4 := load3 (src [13 :]) << 2
h5 := load4 (src [16 :])
h6 := load3 (src [20 :]) << 7
h7 := load3 (src [23 :]) << 5
h8 := load3 (src [26 :]) << 4
h9 := (load3 (src [29 :]) & 0x7fffff ) << 2
var carry [10 ]int64
carry [9 ] = (h9 + 1 <<24 ) >> 25
h0 += carry [9 ] * 19
h9 -= carry [9 ] << 25
carry [1 ] = (h1 + 1 <<24 ) >> 25
h2 += carry [1 ]
h1 -= carry [1 ] << 25
carry [3 ] = (h3 + 1 <<24 ) >> 25
h4 += carry [3 ]
h3 -= carry [3 ] << 25
carry [5 ] = (h5 + 1 <<24 ) >> 25
h6 += carry [5 ]
h5 -= carry [5 ] << 25
carry [7 ] = (h7 + 1 <<24 ) >> 25
h8 += carry [7 ]
h7 -= carry [7 ] << 25
carry [0 ] = (h0 + 1 <<25 ) >> 26
h1 += carry [0 ]
h0 -= carry [0 ] << 26
carry [2 ] = (h2 + 1 <<25 ) >> 26
h3 += carry [2 ]
h2 -= carry [2 ] << 26
carry [4 ] = (h4 + 1 <<25 ) >> 26
h5 += carry [4 ]
h4 -= carry [4 ] << 26
carry [6 ] = (h6 + 1 <<25 ) >> 26
h7 += carry [6 ]
h6 -= carry [6 ] << 26
carry [8 ] = (h8 + 1 <<25 ) >> 26
h9 += carry [8 ]
h8 -= carry [8 ] << 26
dst [0 ] = int32 (h0 )
dst [1 ] = int32 (h1 )
dst [2 ] = int32 (h2 )
dst [3 ] = int32 (h3 )
dst [4 ] = int32 (h4 )
dst [5 ] = int32 (h5 )
dst [6 ] = int32 (h6 )
dst [7 ] = int32 (h7 )
dst [8 ] = int32 (h8 )
dst [9 ] = int32 (h9 )
}
func feToBytes (s *[32 ]byte , h *fieldElement ) {
var carry [10 ]int32
q := (19 *h [9 ] + (1 << 24 )) >> 25
q = (h [0 ] + q ) >> 26
q = (h [1 ] + q ) >> 25
q = (h [2 ] + q ) >> 26
q = (h [3 ] + q ) >> 25
q = (h [4 ] + q ) >> 26
q = (h [5 ] + q ) >> 25
q = (h [6 ] + q ) >> 26
q = (h [7 ] + q ) >> 25
q = (h [8 ] + q ) >> 26
q = (h [9 ] + q ) >> 25
h [0 ] += 19 * q
carry [0 ] = h [0 ] >> 26
h [1 ] += carry [0 ]
h [0 ] -= carry [0 ] << 26
carry [1 ] = h [1 ] >> 25
h [2 ] += carry [1 ]
h [1 ] -= carry [1 ] << 25
carry [2 ] = h [2 ] >> 26
h [3 ] += carry [2 ]
h [2 ] -= carry [2 ] << 26
carry [3 ] = h [3 ] >> 25
h [4 ] += carry [3 ]
h [3 ] -= carry [3 ] << 25
carry [4 ] = h [4 ] >> 26
h [5 ] += carry [4 ]
h [4 ] -= carry [4 ] << 26
carry [5 ] = h [5 ] >> 25
h [6 ] += carry [5 ]
h [5 ] -= carry [5 ] << 25
carry [6 ] = h [6 ] >> 26
h [7 ] += carry [6 ]
h [6 ] -= carry [6 ] << 26
carry [7 ] = h [7 ] >> 25
h [8 ] += carry [7 ]
h [7 ] -= carry [7 ] << 25
carry [8 ] = h [8 ] >> 26
h [9 ] += carry [8 ]
h [8 ] -= carry [8 ] << 26
carry [9 ] = h [9 ] >> 25
h [9 ] -= carry [9 ] << 25
s [0 ] = byte (h [0 ] >> 0 )
s [1 ] = byte (h [0 ] >> 8 )
s [2 ] = byte (h [0 ] >> 16 )
s [3 ] = byte ((h [0 ] >> 24 ) | (h [1 ] << 2 ))
s [4 ] = byte (h [1 ] >> 6 )
s [5 ] = byte (h [1 ] >> 14 )
s [6 ] = byte ((h [1 ] >> 22 ) | (h [2 ] << 3 ))
s [7 ] = byte (h [2 ] >> 5 )
s [8 ] = byte (h [2 ] >> 13 )
s [9 ] = byte ((h [2 ] >> 21 ) | (h [3 ] << 5 ))
s [10 ] = byte (h [3 ] >> 3 )
s [11 ] = byte (h [3 ] >> 11 )
s [12 ] = byte ((h [3 ] >> 19 ) | (h [4 ] << 6 ))
s [13 ] = byte (h [4 ] >> 2 )
s [14 ] = byte (h [4 ] >> 10 )
s [15 ] = byte (h [4 ] >> 18 )
s [16 ] = byte (h [5 ] >> 0 )
s [17 ] = byte (h [5 ] >> 8 )
s [18 ] = byte (h [5 ] >> 16 )
s [19 ] = byte ((h [5 ] >> 24 ) | (h [6 ] << 1 ))
s [20 ] = byte (h [6 ] >> 7 )
s [21 ] = byte (h [6 ] >> 15 )
s [22 ] = byte ((h [6 ] >> 23 ) | (h [7 ] << 3 ))
s [23 ] = byte (h [7 ] >> 5 )
s [24 ] = byte (h [7 ] >> 13 )
s [25 ] = byte ((h [7 ] >> 21 ) | (h [8 ] << 4 ))
s [26 ] = byte (h [8 ] >> 4 )
s [27 ] = byte (h [8 ] >> 12 )
s [28 ] = byte ((h [8 ] >> 20 ) | (h [9 ] << 6 ))
s [29 ] = byte (h [9 ] >> 2 )
s [30 ] = byte (h [9 ] >> 10 )
s [31 ] = byte (h [9 ] >> 18 )
}
func feMul (h , f , g *fieldElement ) {
f0 := f [0 ]
f1 := f [1 ]
f2 := f [2 ]
f3 := f [3 ]
f4 := f [4 ]
f5 := f [5 ]
f6 := f [6 ]
f7 := f [7 ]
f8 := f [8 ]
f9 := f [9 ]
g0 := g [0 ]
g1 := g [1 ]
g2 := g [2 ]
g3 := g [3 ]
g4 := g [4 ]
g5 := g [5 ]
g6 := g [6 ]
g7 := g [7 ]
g8 := g [8 ]
g9 := g [9 ]
g1_19 := 19 * g1
g2_19 := 19 * g2
g3_19 := 19 * g3
g4_19 := 19 * g4
g5_19 := 19 * g5
g6_19 := 19 * g6
g7_19 := 19 * g7
g8_19 := 19 * g8
g9_19 := 19 * g9
f1_2 := 2 * f1
f3_2 := 2 * f3
f5_2 := 2 * f5
f7_2 := 2 * f7
f9_2 := 2 * f9
f0g0 := int64 (f0 ) * int64 (g0 )
f0g1 := int64 (f0 ) * int64 (g1 )
f0g2 := int64 (f0 ) * int64 (g2 )
f0g3 := int64 (f0 ) * int64 (g3 )
f0g4 := int64 (f0 ) * int64 (g4 )
f0g5 := int64 (f0 ) * int64 (g5 )
f0g6 := int64 (f0 ) * int64 (g6 )
f0g7 := int64 (f0 ) * int64 (g7 )
f0g8 := int64 (f0 ) * int64 (g8 )
f0g9 := int64 (f0 ) * int64 (g9 )
f1g0 := int64 (f1 ) * int64 (g0 )
f1g1_2 := int64 (f1_2 ) * int64 (g1 )
f1g2 := int64 (f1 ) * int64 (g2 )
f1g3_2 := int64 (f1_2 ) * int64 (g3 )
f1g4 := int64 (f1 ) * int64 (g4 )
f1g5_2 := int64 (f1_2 ) * int64 (g5 )
f1g6 := int64 (f1 ) * int64 (g6 )
f1g7_2 := int64 (f1_2 ) * int64 (g7 )
f1g8 := int64 (f1 ) * int64 (g8 )
f1g9_38 := int64 (f1_2 ) * int64 (g9_19 )
f2g0 := int64 (f2 ) * int64 (g0 )
f2g1 := int64 (f2 ) * int64 (g1 )
f2g2 := int64 (f2 ) * int64 (g2 )
f2g3 := int64 (f2 ) * int64 (g3 )
f2g4 := int64 (f2 ) * int64 (g4 )
f2g5 := int64 (f2 ) * int64 (g5 )
f2g6 := int64 (f2 ) * int64 (g6 )
f2g7 := int64 (f2 ) * int64 (g7 )
f2g8_19 := int64 (f2 ) * int64 (g8_19 )
f2g9_19 := int64 (f2 ) * int64 (g9_19 )
f3g0 := int64 (f3 ) * int64 (g0 )
f3g1_2 := int64 (f3_2 ) * int64 (g1 )
f3g2 := int64 (f3 ) * int64 (g2 )
f3g3_2 := int64 (f3_2 ) * int64 (g3 )
f3g4 := int64 (f3 ) * int64 (g4 )
f3g5_2 := int64 (f3_2 ) * int64 (g5 )
f3g6 := int64 (f3 ) * int64 (g6 )
f3g7_38 := int64 (f3_2 ) * int64 (g7_19 )
f3g8_19 := int64 (f3 ) * int64 (g8_19 )
f3g9_38 := int64 (f3_2 ) * int64 (g9_19 )
f4g0 := int64 (f4 ) * int64 (g0 )
f4g1 := int64 (f4 ) * int64 (g1 )
f4g2 := int64 (f4 ) * int64 (g2 )
f4g3 := int64 (f4 ) * int64 (g3 )
f4g4 := int64 (f4 ) * int64 (g4 )
f4g5 := int64 (f4 ) * int64 (g5 )
f4g6_19 := int64 (f4 ) * int64 (g6_19 )
f4g7_19 := int64 (f4 ) * int64 (g7_19 )
f4g8_19 := int64 (f4 ) * int64 (g8_19 )
f4g9_19 := int64 (f4 ) * int64 (g9_19 )
f5g0 := int64 (f5 ) * int64 (g0 )
f5g1_2 := int64 (f5_2 ) * int64 (g1 )
f5g2 := int64 (f5 ) * int64 (g2 )
f5g3_2 := int64 (f5_2 ) * int64 (g3 )
f5g4 := int64 (f5 ) * int64 (g4 )
f5g5_38 := int64 (f5_2 ) * int64 (g5_19 )
f5g6_19 := int64 (f5 ) * int64 (g6_19 )
f5g7_38 := int64 (f5_2 ) * int64 (g7_19 )
f5g8_19 := int64 (f5 ) * int64 (g8_19 )
f5g9_38 := int64 (f5_2 ) * int64 (g9_19 )
f6g0 := int64 (f6 ) * int64 (g0 )
f6g1 := int64 (f6 ) * int64 (g1 )
f6g2 := int64 (f6 ) * int64 (g2 )
f6g3 := int64 (f6 ) * int64 (g3 )
f6g4_19 := int64 (f6 ) * int64 (g4_19 )
f6g5_19 := int64 (f6 ) * int64 (g5_19 )
f6g6_19 := int64 (f6 ) * int64 (g6_19 )
f6g7_19 := int64 (f6 ) * int64 (g7_19 )
f6g8_19 := int64 (f6 ) * int64 (g8_19 )
f6g9_19 := int64 (f6 ) * int64 (g9_19 )
f7g0 := int64 (f7 ) * int64 (g0 )
f7g1_2 := int64 (f7_2 ) * int64 (g1 )
f7g2 := int64 (f7 ) * int64 (g2 )
f7g3_38 := int64 (f7_2 ) * int64 (g3_19 )
f7g4_19 := int64 (f7 ) * int64 (g4_19 )
f7g5_38 := int64 (f7_2 ) * int64 (g5_19 )
f7g6_19 := int64 (f7 ) * int64 (g6_19 )
f7g7_38 := int64 (f7_2 ) * int64 (g7_19 )
f7g8_19 := int64 (f7 ) * int64 (g8_19 )
f7g9_38 := int64 (f7_2 ) * int64 (g9_19 )
f8g0 := int64 (f8 ) * int64 (g0 )
f8g1 := int64 (f8 ) * int64 (g1 )
f8g2_19 := int64 (f8 ) * int64 (g2_19 )
f8g3_19 := int64 (f8 ) * int64 (g3_19 )
f8g4_19 := int64 (f8 ) * int64 (g4_19 )
f8g5_19 := int64 (f8 ) * int64 (g5_19 )
f8g6_19 := int64 (f8 ) * int64 (g6_19 )
f8g7_19 := int64 (f8 ) * int64 (g7_19 )
f8g8_19 := int64 (f8 ) * int64 (g8_19 )
f8g9_19 := int64 (f8 ) * int64 (g9_19 )
f9g0 := int64 (f9 ) * int64 (g0 )
f9g1_38 := int64 (f9_2 ) * int64 (g1_19 )
f9g2_19 := int64 (f9 ) * int64 (g2_19 )
f9g3_38 := int64 (f9_2 ) * int64 (g3_19 )
f9g4_19 := int64 (f9 ) * int64 (g4_19 )
f9g5_38 := int64 (f9_2 ) * int64 (g5_19 )
f9g6_19 := int64 (f9 ) * int64 (g6_19 )
f9g7_38 := int64 (f9_2 ) * int64 (g7_19 )
f9g8_19 := int64 (f9 ) * int64 (g8_19 )
f9g9_38 := int64 (f9_2 ) * int64 (g9_19 )
h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38
h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19
h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38
h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19
h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38
h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19
h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38
h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19
h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38
h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0
var carry [10 ]int64
carry [0 ] = (h0 + (1 << 25 )) >> 26
h1 += carry [0 ]
h0 -= carry [0 ] << 26
carry [4 ] = (h4 + (1 << 25 )) >> 26
h5 += carry [4 ]
h4 -= carry [4 ] << 26
carry [1 ] = (h1 + (1 << 24 )) >> 25
h2 += carry [1 ]
h1 -= carry [1 ] << 25
carry [5 ] = (h5 + (1 << 24 )) >> 25
h6 += carry [5 ]
h5 -= carry [5 ] << 25
carry [2 ] = (h2 + (1 << 25 )) >> 26
h3 += carry [2 ]
h2 -= carry [2 ] << 26
carry [6 ] = (h6 + (1 << 25 )) >> 26
h7 += carry [6 ]
h6 -= carry [6 ] << 26
carry [3 ] = (h3 + (1 << 24 )) >> 25
h4 += carry [3 ]
h3 -= carry [3 ] << 25
carry [7 ] = (h7 + (1 << 24 )) >> 25
h8 += carry [7 ]
h7 -= carry [7 ] << 25
carry [4 ] = (h4 + (1 << 25 )) >> 26
h5 += carry [4 ]
h4 -= carry [4 ] << 26
carry [8 ] = (h8 + (1 << 25 )) >> 26
h9 += carry [8 ]
h8 -= carry [8 ] << 26
carry [9 ] = (h9 + (1 << 24 )) >> 25
h0 += carry [9 ] * 19
h9 -= carry [9 ] << 25
carry [0 ] = (h0 + (1 << 25 )) >> 26
h1 += carry [0 ]
h0 -= carry [0 ] << 26
h [0 ] = int32 (h0 )
h [1 ] = int32 (h1 )
h [2 ] = int32 (h2 )
h [3 ] = int32 (h3 )
h [4 ] = int32 (h4 )
h [5 ] = int32 (h5 )
h [6 ] = int32 (h6 )
h [7 ] = int32 (h7 )
h [8 ] = int32 (h8 )
h [9 ] = int32 (h9 )
}
func feSquare (h , f *fieldElement ) {
f0 := f [0 ]
f1 := f [1 ]
f2 := f [2 ]
f3 := f [3 ]
f4 := f [4 ]
f5 := f [5 ]
f6 := f [6 ]
f7 := f [7 ]
f8 := f [8 ]
f9 := f [9 ]
f0_2 := 2 * f0
f1_2 := 2 * f1
f2_2 := 2 * f2
f3_2 := 2 * f3
f4_2 := 2 * f4
f5_2 := 2 * f5
f6_2 := 2 * f6
f7_2 := 2 * f7
f5_38 := 38 * f5
f6_19 := 19 * f6
f7_38 := 38 * f7
f8_19 := 19 * f8
f9_38 := 38 * f9
f0f0 := int64 (f0 ) * int64 (f0 )
f0f1_2 := int64 (f0_2 ) * int64 (f1 )
f0f2_2 := int64 (f0_2 ) * int64 (f2 )
f0f3_2 := int64 (f0_2 ) * int64 (f3 )
f0f4_2 := int64 (f0_2 ) * int64 (f4 )
f0f5_2 := int64 (f0_2 ) * int64 (f5 )
f0f6_2 := int64 (f0_2 ) * int64 (f6 )
f0f7_2 := int64 (f0_2 ) * int64 (f7 )
f0f8_2 := int64 (f0_2 ) * int64 (f8 )
f0f9_2 := int64 (f0_2 ) * int64 (f9 )
f1f1_2 := int64 (f1_2 ) * int64 (f1 )
f1f2_2 := int64 (f1_2 ) * int64 (f2 )
f1f3_4 := int64 (f1_2 ) * int64 (f3_2 )
f1f4_2 := int64 (f1_2 ) * int64 (f4 )
f1f5_4 := int64 (f1_2 ) * int64 (f5_2 )
f1f6_2 := int64 (f1_2 ) * int64 (f6 )
f1f7_4 := int64 (f1_2 ) * int64 (f7_2 )
f1f8_2 := int64 (f1_2 ) * int64 (f8 )
f1f9_76 := int64 (f1_2 ) * int64 (f9_38 )
f2f2 := int64 (f2 ) * int64 (f2 )
f2f3_2 := int64 (f2_2 ) * int64 (f3 )
f2f4_2 := int64 (f2_2 ) * int64 (f4 )
f2f5_2 := int64 (f2_2 ) * int64 (f5 )
f2f6_2 := int64 (f2_2 ) * int64 (f6 )
f2f7_2 := int64 (f2_2 ) * int64 (f7 )
f2f8_38 := int64 (f2_2 ) * int64 (f8_19 )
f2f9_38 := int64 (f2 ) * int64 (f9_38 )
f3f3_2 := int64 (f3_2 ) * int64 (f3 )
f3f4_2 := int64 (f3_2 ) * int64 (f4 )
f3f5_4 := int64 (f3_2 ) * int64 (f5_2 )
f3f6_2 := int64 (f3_2 ) * int64 (f6 )
f3f7_76 := int64 (f3_2 ) * int64 (f7_38 )
f3f8_38 := int64 (f3_2 ) * int64 (f8_19 )
f3f9_76 := int64 (f3_2 ) * int64 (f9_38 )
f4f4 := int64 (f4 ) * int64 (f4 )
f4f5_2 := int64 (f4_2 ) * int64 (f5 )
f4f6_38 := int64 (f4_2 ) * int64 (f6_19 )
f4f7_38 := int64 (f4 ) * int64 (f7_38 )
f4f8_38 := int64 (f4_2 ) * int64 (f8_19 )
f4f9_38 := int64 (f4 ) * int64 (f9_38 )
f5f5_38 := int64 (f5 ) * int64 (f5_38 )
f5f6_38 := int64 (f5_2 ) * int64 (f6_19 )
f5f7_76 := int64 (f5_2 ) * int64 (f7_38 )
f5f8_38 := int64 (f5_2 ) * int64 (f8_19 )
f5f9_76 := int64 (f5_2 ) * int64 (f9_38 )
f6f6_19 := int64 (f6 ) * int64 (f6_19 )
f6f7_38 := int64 (f6 ) * int64 (f7_38 )
f6f8_38 := int64 (f6_2 ) * int64 (f8_19 )
f6f9_38 := int64 (f6 ) * int64 (f9_38 )
f7f7_38 := int64 (f7 ) * int64 (f7_38 )
f7f8_38 := int64 (f7_2 ) * int64 (f8_19 )
f7f9_76 := int64 (f7_2 ) * int64 (f9_38 )
f8f8_19 := int64 (f8 ) * int64 (f8_19 )
f8f9_38 := int64 (f8 ) * int64 (f9_38 )
f9f9_38 := int64 (f9 ) * int64 (f9_38 )
h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38
h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38
h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19
h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38
h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38
h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38
h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19
h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38
h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38
h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2
var carry [10 ]int64
carry [0 ] = (h0 + (1 << 25 )) >> 26
h1 += carry [0 ]
h0 -= carry [0 ] << 26
carry [4 ] = (h4 + (1 << 25 )) >> 26
h5 += carry [4 ]
h4 -= carry [4 ] << 26
carry [1 ] = (h1 + (1 << 24 )) >> 25
h2 += carry [1 ]
h1 -= carry [1 ] << 25
carry [5 ] = (h5 + (1 << 24 )) >> 25
h6 += carry [5 ]
h5 -= carry [5 ] << 25
carry [2 ] = (h2 + (1 << 25 )) >> 26
h3 += carry [2 ]
h2 -= carry [2 ] << 26
carry [6 ] = (h6 + (1 << 25 )) >> 26
h7 += carry [6 ]
h6 -= carry [6 ] << 26
carry [3 ] = (h3 + (1 << 24 )) >> 25
h4 += carry [3 ]
h3 -= carry [3 ] << 25
carry [7 ] = (h7 + (1 << 24 )) >> 25
h8 += carry [7 ]
h7 -= carry [7 ] << 25
carry [4 ] = (h4 + (1 << 25 )) >> 26
h5 += carry [4 ]
h4 -= carry [4 ] << 26
carry [8 ] = (h8 + (1 << 25 )) >> 26
h9 += carry [8 ]
h8 -= carry [8 ] << 26
carry [9 ] = (h9 + (1 << 24 )) >> 25
h0 += carry [9 ] * 19
h9 -= carry [9 ] << 25
carry [0 ] = (h0 + (1 << 25 )) >> 26
h1 += carry [0 ]
h0 -= carry [0 ] << 26
h [0 ] = int32 (h0 )
h [1 ] = int32 (h1 )
h [2 ] = int32 (h2 )
h [3 ] = int32 (h3 )
h [4 ] = int32 (h4 )
h [5 ] = int32 (h5 )
h [6 ] = int32 (h6 )
h [7 ] = int32 (h7 )
h [8 ] = int32 (h8 )
h [9 ] = int32 (h9 )
}
func feMul121666 (h , f *fieldElement ) {
h0 := int64 (f [0 ]) * 121666
h1 := int64 (f [1 ]) * 121666
h2 := int64 (f [2 ]) * 121666
h3 := int64 (f [3 ]) * 121666
h4 := int64 (f [4 ]) * 121666
h5 := int64 (f [5 ]) * 121666
h6 := int64 (f [6 ]) * 121666
h7 := int64 (f [7 ]) * 121666
h8 := int64 (f [8 ]) * 121666
h9 := int64 (f [9 ]) * 121666
var carry [10 ]int64
carry [9 ] = (h9 + (1 << 24 )) >> 25
h0 += carry [9 ] * 19
h9 -= carry [9 ] << 25
carry [1 ] = (h1 + (1 << 24 )) >> 25
h2 += carry [1 ]
h1 -= carry [1 ] << 25
carry [3 ] = (h3 + (1 << 24 )) >> 25
h4 += carry [3 ]
h3 -= carry [3 ] << 25
carry [5 ] = (h5 + (1 << 24 )) >> 25
h6 += carry [5 ]
h5 -= carry [5 ] << 25
carry [7 ] = (h7 + (1 << 24 )) >> 25
h8 += carry [7 ]
h7 -= carry [7 ] << 25
carry [0 ] = (h0 + (1 << 25 )) >> 26
h1 += carry [0 ]
h0 -= carry [0 ] << 26
carry [2 ] = (h2 + (1 << 25 )) >> 26
h3 += carry [2 ]
h2 -= carry [2 ] << 26
carry [4 ] = (h4 + (1 << 25 )) >> 26
h5 += carry [4 ]
h4 -= carry [4 ] << 26
carry [6 ] = (h6 + (1 << 25 )) >> 26
h7 += carry [6 ]
h6 -= carry [6 ] << 26
carry [8 ] = (h8 + (1 << 25 )) >> 26
h9 += carry [8 ]
h8 -= carry [8 ] << 26
h [0 ] = int32 (h0 )
h [1 ] = int32 (h1 )
h [2 ] = int32 (h2 )
h [3 ] = int32 (h3 )
h [4 ] = int32 (h4 )
h [5 ] = int32 (h5 )
h [6 ] = int32 (h6 )
h [7 ] = int32 (h7 )
h [8 ] = int32 (h8 )
h [9 ] = int32 (h9 )
}
func feInvert (out , z *fieldElement ) {
var t0 , t1 , t2 , t3 fieldElement
var i int
feSquare (&t0 , z )
for i = 1 ; i < 1 ; i ++ {
feSquare (&t0 , &t0 )
}
feSquare (&t1 , &t0 )
for i = 1 ; i < 2 ; i ++ {
feSquare (&t1 , &t1 )
}
feMul (&t1 , z , &t1 )
feMul (&t0 , &t0 , &t1 )
feSquare (&t2 , &t0 )
for i = 1 ; i < 1 ; i ++ {
feSquare (&t2 , &t2 )
}
feMul (&t1 , &t1 , &t2 )
feSquare (&t2 , &t1 )
for i = 1 ; i < 5 ; i ++ {
feSquare (&t2 , &t2 )
}
feMul (&t1 , &t2 , &t1 )
feSquare (&t2 , &t1 )
for i = 1 ; i < 10 ; i ++ {
feSquare (&t2 , &t2 )
}
feMul (&t2 , &t2 , &t1 )
feSquare (&t3 , &t2 )
for i = 1 ; i < 20 ; i ++ {
feSquare (&t3 , &t3 )
}
feMul (&t2 , &t3 , &t2 )
feSquare (&t2 , &t2 )
for i = 1 ; i < 10 ; i ++ {
feSquare (&t2 , &t2 )
}
feMul (&t1 , &t2 , &t1 )
feSquare (&t2 , &t1 )
for i = 1 ; i < 50 ; i ++ {
feSquare (&t2 , &t2 )
}
feMul (&t2 , &t2 , &t1 )
feSquare (&t3 , &t2 )
for i = 1 ; i < 100 ; i ++ {
feSquare (&t3 , &t3 )
}
feMul (&t2 , &t3 , &t2 )
feSquare (&t2 , &t2 )
for i = 1 ; i < 50 ; i ++ {
feSquare (&t2 , &t2 )
}
feMul (&t1 , &t2 , &t1 )
feSquare (&t1 , &t1 )
for i = 1 ; i < 5 ; i ++ {
feSquare (&t1 , &t1 )
}
feMul (out , &t1 , &t0 )
}
func scalarMultGeneric (out , in , base *[32 ]byte ) {
var e [32 ]byte
copy (e [:], in [:])
e [0 ] &= 248
e [31 ] &= 127
e [31 ] |= 64
var x1 , x2 , z2 , x3 , z3 , tmp0 , tmp1 fieldElement
feFromBytes (&x1 , base )
feOne (&x2 )
feCopy (&x3 , &x1 )
feOne (&z3 )
swap := int32 (0 )
for pos := 254 ; pos >= 0 ; pos -- {
b := e [pos /8 ] >> uint (pos &7 )
b &= 1
swap ^= int32 (b )
feCSwap (&x2 , &x3 , swap )
feCSwap (&z2 , &z3 , swap )
swap = int32 (b )
feSub (&tmp0 , &x3 , &z3 )
feSub (&tmp1 , &x2 , &z2 )
feAdd (&x2 , &x2 , &z2 )
feAdd (&z2 , &x3 , &z3 )
feMul (&z3 , &tmp0 , &x2 )
feMul (&z2 , &z2 , &tmp1 )
feSquare (&tmp0 , &tmp1 )
feSquare (&tmp1 , &x2 )
feAdd (&x3 , &z3 , &z2 )
feSub (&z2 , &z3 , &z2 )
feMul (&x2 , &tmp1 , &tmp0 )
feSub (&tmp1 , &tmp1 , &tmp0 )
feSquare (&z2 , &z2 )
feMul121666 (&z3 , &tmp1 )
feSquare (&x3 , &x3 )
feAdd (&tmp0 , &tmp0 , &z3 )
feMul (&z3 , &x1 , &z2 )
feMul (&z2 , &tmp1 , &tmp0 )
}
feCSwap (&x2 , &x3 , swap )
feCSwap (&z2 , &z3 , swap )
feInvert (&z2 , &z2 )
feMul (&x2 , &x2 , &z2 )
feToBytes (out , &x2 )
}
The pages are generated with Golds v0.3.6 . (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .