github.com/cloudflare/circl@v1.5.0/dh/csidh/utils_test.go (about) 1 package csidh 2 3 import ( 4 "crypto/rand" 5 "encoding/binary" 6 "fmt" 7 "math/big" 8 ) 9 10 var ( 11 // Number of iterations 12 numIter = 10 13 // Modulus 14 modulus, _ = new(big.Int).SetString(fp2S(p), 16) 15 // Zero in fp 16 zeroFp512 = fp{} 17 // One in fp 18 oneFp512 = fp{1, 0, 0, 0, 0, 0, 0, 0} 19 // file with KAT vectors 20 katFile = "testdata/csidh_testvectors.json" 21 ) 22 23 // Converts dst to Montgomery if "toMont==true" or from Montgomery domain otherwise. 24 func toMont(dst *big.Int, toMont bool) { 25 var bigP, bigR big.Int 26 27 intSetU64(&bigP, p[:]) 28 bigR.SetUint64(1) 29 bigR.Lsh(&bigR, 512) 30 31 if !toMont { 32 bigR.ModInverse(&bigR, &bigP) 33 } 34 dst.Mul(dst, &bigR) 35 dst.Mod(dst, &bigP) 36 } 37 38 func fp2S(v fp) string { 39 var str string 40 for i := 0; i < 8; i++ { 41 str = fmt.Sprintf("%016x", v[i]) + str 42 } 43 return str 44 } 45 46 // zeroize fp. 47 func zero(v *fp) { 48 for i := range *v { 49 v[i] = 0 50 } 51 } 52 53 // returns random value in a range (0,p). 54 func randomFp() (u fp) { 55 _ = binary.Read(rand.Reader, binary.LittleEndian, &u) 56 return 57 } 58 59 // return x==y for fp. 60 func eqFp(l, r *fp) bool { 61 for idx := range l { 62 if l[idx] != r[idx] { 63 return false 64 } 65 } 66 return true 67 } 68 69 // return x==y for point. 70 func ceqpoint(l, r *point) bool { 71 return eqFp(&l.x, &r.x) && eqFp(&l.z, &r.z) 72 } 73 74 // Converts src to big.Int. Function assumes that src is a slice of uint64 75 // values encoded in little-endian byte order. 76 func intSetU64(dst *big.Int, src []uint64) { 77 var tmp big.Int 78 79 dst.SetUint64(0) 80 for i := range src { 81 tmp.SetUint64(src[i]) 82 tmp.Lsh(&tmp, uint(i*64)) 83 dst.Add(dst, &tmp) 84 } 85 } 86 87 // Converts src to an array of uint64 values encoded in little-endian 88 // byte order. 89 func intGetU64(src *big.Int) []uint64 { 90 var tmp, mod big.Int 91 dst := make([]uint64, (src.BitLen()/64)+1) 92 93 u64 := uint64(0) 94 u64-- 95 mod.SetUint64(u64) 96 for i := 0; i < (src.BitLen()/64)+1; i++ { 97 tmp.Set(src) 98 tmp.Rsh(&tmp, uint(i)*64) 99 tmp.And(&tmp, &mod) 100 dst[i] = tmp.Uint64() 101 } 102 return dst 103 } 104 105 // Returns projective coordinate X of normalized EC 'point' (point.x / point.z). 106 func toNormX(point *point) big.Int { 107 var bigP, bigDnt, bigDor big.Int 108 109 intSetU64(&bigP, p[:]) 110 intSetU64(&bigDnt, point.x[:]) 111 intSetU64(&bigDor, point.z[:]) 112 113 bigDor.ModInverse(&bigDor, &bigP) 114 bigDnt.Mul(&bigDnt, &bigDor) 115 bigDnt.Mod(&bigDnt, &bigP) 116 return bigDnt 117 } 118 119 // Converts string to fp element in Montgomery domain of cSIDH-512. 120 func toFp(num string) fp { 121 var tmp big.Int 122 var ok bool 123 var ret fp 124 125 _, ok = tmp.SetString(num, 0) 126 if !ok { 127 panic("Can't parse a number") 128 } 129 toMont(&tmp, true) 130 copy(ret[:], intGetU64(&tmp)) 131 return ret 132 }